aacp branch removed as we already have commited everything
This commit is contained in:
parent
ccd4d54df8
commit
27cf3ff79d
|
@ -1,38 +0,0 @@
|
||||||
DarkIce is being written by:
|
|
||||||
|
|
||||||
Akos Maroy, <darkeye@users.sourceforge.net>
|
|
||||||
|
|
||||||
with contributions by:
|
|
||||||
|
|
||||||
Jim Crilly, <JCrilly@MSA.com>
|
|
||||||
aNa|0Gue, <analogue@glop.org>
|
|
||||||
Robin P. Blanchard, <Robin_Blanchard@gactr.uga.edu>
|
|
||||||
Tom Gray, <tomg@future-i.com>
|
|
||||||
Michael Smith, <msmith@labyrinth.net.au>
|
|
||||||
Julius O. Smith, <jos@ccrma.stanford.edu>
|
|
||||||
the OSALP team, http://osalp.sourceforge.net
|
|
||||||
Kristjan G. Bjarnason <kgb@gangverk.is>
|
|
||||||
Nicu Pavel <npavel@ituner.com>
|
|
||||||
Kai Krakow <kai@kaishome.de>
|
|
||||||
Atsuhiko Yamanaka <ymnk@jcraft.com>
|
|
||||||
Ricardo Galli <gallir@uib.es>
|
|
||||||
John Hay <jhay@icomtek.csir.co.za>
|
|
||||||
Christian Forster <forster@like.e-technik.uni-erlangen.de>
|
|
||||||
John Deeny <taqueso@dilapidated.org>
|
|
||||||
Robert Lunnon <bobl@optushome.com.au>
|
|
||||||
Enrico Ardizzoni <craken@users.sourceforge.net>
|
|
||||||
Deti Fliegl <deti@fliegl.de>
|
|
||||||
Nicholas J. Humfrey <njh@ecs.soton.ac.uk>
|
|
||||||
Joel Ebel <jbebel@ncsu.edu>
|
|
||||||
<jochen2@users.sourceforge.net>
|
|
||||||
Alexander Vlasov <zulu@galaradio.com>
|
|
||||||
Mariusz Mazur <mmazur@kernel.pl>
|
|
||||||
dsk <derrick@csociety.org>
|
|
||||||
Clyde Stubbs <clyde@htsoft.com>
|
|
||||||
Jens Maurer <Jens.Maurer@gmx.net>
|
|
||||||
Elod Horvath <elod@itfais.com>
|
|
||||||
Pierre Souchay <pierre@souchay.net>
|
|
||||||
Daniel Hazelbaker <daniel@highdesertchurch.com>
|
|
||||||
Alessandro Beretta <alessandro.baretta@radiomaria.org>
|
|
||||||
Roland Hermans <roland.hermans@omroepvenray.nl>
|
|
||||||
|
|
|
@ -1,345 +0,0 @@
|
||||||
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.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 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.
|
|
|
@ -1,238 +0,0 @@
|
||||||
DarkIce next release
|
|
||||||
|
|
||||||
o bugfix: the configure script recognizes Ogg Vorbis shared objects
|
|
||||||
now, not just static libraries. Thanks to omroepvenray.
|
|
||||||
o bugfix: enabling jack source compilation on Debian Lenny,
|
|
||||||
thanks to Alessandro Beretta <alessandro.baretta@radiomaria.org>
|
|
||||||
|
|
||||||
07-07-2008 Darkice 0.19 released
|
|
||||||
|
|
||||||
o added mount point option for Darwin Streaming Server
|
|
||||||
thanks to Pierre Souchay <pierre@souchay.net>
|
|
||||||
o fix for some reliablity issues when using a Jack source
|
|
||||||
thanks to Pierre Souchay <pierre@souchay.net>
|
|
||||||
o enable easier finding of jack libraries on MacOS X,
|
|
||||||
thanks to Daniel Hazelbaker <daniel@highdesertchurch.com>
|
|
||||||
o added ability to specify name of jack device created by darkice,
|
|
||||||
thanks to Alessandro Beretta <alessandro.baretta@radiomaria.org>
|
|
||||||
|
|
||||||
26-04-2007 DarkIce 0.18.1 released
|
|
||||||
|
|
||||||
o enable real-time scheduling for non-super-users, if they have
|
|
||||||
the proper operating system permissions,
|
|
||||||
thanks to Jens Maurer <Jens.Maurer@gmx.net>
|
|
||||||
o fix to enable compliation of the Serial ULAW code on MacOS X,
|
|
||||||
thanks to Elod Horvath <elod@itfais.com>
|
|
||||||
o fix to solve Shoutcast login failures, introduced in 0.18
|
|
||||||
|
|
||||||
05-03-2007 DarkIce 0.18 released
|
|
||||||
|
|
||||||
o added serial ulaw input device support, thanks to
|
|
||||||
Clyde Stubbs <clyde@htsoft.com>
|
|
||||||
o improvements on reconnecting:
|
|
||||||
added TCP connection keep-alive to TCP sockets
|
|
||||||
added graceful sleep when trying to reconnect
|
|
||||||
o added user-defined date formatting for the fileAddDate options,
|
|
||||||
thanks to dsk <derrick@csociety.org>
|
|
||||||
o added logging facility - [file-X] targets will cut the saved file
|
|
||||||
and rename it as needed when darkice recieves the SIGUSR1 signal
|
|
||||||
o added default configuration file handling - if no configuration file
|
|
||||||
is specified, /etc/darkice.cfg is used
|
|
||||||
o fix to enable compiling on 64 bit platforms
|
|
||||||
thanks to Alexander Vlasov <zulu@galaradio.com> and
|
|
||||||
Mariusz Mazur <mmazur@kernel.pl>
|
|
||||||
o fix to enable file dump feature using ogg vorbis.
|
|
||||||
thanks to dsk <derrick@csociety.org>
|
|
||||||
o fix to enable compiling with jack installed at arbitrary locations
|
|
||||||
|
|
||||||
19-05-2006 DarkIce 0.17.1 released
|
|
||||||
|
|
||||||
o bugfix: automatic reconnect works more reliably
|
|
||||||
|
|
||||||
26-01-2006 DarkIce 0.17 released
|
|
||||||
|
|
||||||
o added check for bufferSecs set to 0
|
|
||||||
thanks to Toph <fangiotophia@gmail.com>
|
|
||||||
o added realtime parameter to the general section
|
|
||||||
o added MPEG2 support through the TwoLame library.
|
|
||||||
thanks to Nicholas J Humfrey <njh@ecs.soton.ac.uk>
|
|
||||||
|
|
||||||
22-10-2005 DarkIce 0.16 released
|
|
||||||
|
|
||||||
o added AAC support through the faac codec, http://www.audiocoding.com
|
|
||||||
o bug fix: icecast2 sections didn't honor lowpass or highpass filters
|
|
||||||
when using the mp3 format
|
|
||||||
|
|
||||||
14-04-2005 DarkIce 0.15 released
|
|
||||||
|
|
||||||
o ported to OpenBSD and NetBSD, though real-time scheduling not supported,
|
|
||||||
since it is not implemented in OpenBSD / NetBSD
|
|
||||||
o added possibility to downsample from stereo to mono when encoding
|
|
||||||
to Ogg Vorbis, thanks to Deti Fliegl, <deti@fliegl.de>
|
|
||||||
o added support for Jack inputs, enabling a lot of interesting usage,
|
|
||||||
including support for MacOS X.
|
|
||||||
Thanks to Nicholas J. Humfrey <njh@ecs.soton.ac.uk>
|
|
||||||
o various improvements by Joel Ebel <jbebel@ncsu.edu>
|
|
||||||
o added option to turn off automatic reconnect feature
|
|
||||||
o added IPv6 support, thanks to <jochen2@users.sourceforge.net>
|
|
||||||
|
|
||||||
15-02-2004: DarkIce 0.14 released
|
|
||||||
|
|
||||||
o added ALSA support, thanks to Christian Forster
|
|
||||||
<forster@like.e-technik.uni-erlangen.de>
|
|
||||||
o added fix to enable downsampling from stereo to mono of mp3 streams
|
|
||||||
when streaming to an icecast2 server. thanks to John Deeny
|
|
||||||
<taqueso@dilapidated.org>
|
|
||||||
o removed _X and _Y symbols from aflibConverter files, which caused
|
|
||||||
a naming collision on Solaris. thanks to Robert Lunnon,
|
|
||||||
<bobl@optushome.com.au>
|
|
||||||
o bug fix: ogg vorbis recording to only a file caused a segfault.
|
|
||||||
now fixed, thanks to Enrico Ardizzoni <craken@users.sourceforge.net>
|
|
||||||
|
|
||||||
07-01-2004: DarkIce 0.13.2 released
|
|
||||||
|
|
||||||
o bug fix: two bugs fixed that caused core dump when encoding into
|
|
||||||
mp3 of FreeBSD. thanks to John Hay <jhay@icomtek.csir.co.za>
|
|
||||||
o added configure option --with-debug to enable compilation for debug mode
|
|
||||||
|
|
||||||
12-02-2003: Darkice 0.13.1 released
|
|
||||||
|
|
||||||
o added cross-platform pthread detection, thanks to
|
|
||||||
Steven G. Johnson <stevenj@alum.mit.edu> and
|
|
||||||
Alejandro Forero Cuervo <bachue@bachue.com>
|
|
||||||
see http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html
|
|
||||||
o added proper detection of netural endiannes for 16 bit recording
|
|
||||||
o basically these changes allow compilation on FreeBSD
|
|
||||||
|
|
||||||
09-02-2003: DarkIce 0.13 released
|
|
||||||
|
|
||||||
o added feature for setting the TITLE comment field for vorbis
|
|
||||||
streams. thanks to Ricardo Galli <gallir@uib.es>
|
|
||||||
o bugfix: fixed minor bug in IcecCast2.cpp, which could have lead to
|
|
||||||
a buffer overflow. thanks to Atsuhiko Yamanaka <ymnk@jcraft.com>
|
|
||||||
o bugfix: MultiThreadedConnector::sinkThread() was private, now public
|
|
||||||
o added fileAddDate configuration option
|
|
||||||
thanks to Nicu Pavel <npavel@ituner.com>
|
|
||||||
o added support for big endian OSS devices (like Linux PowerPC)
|
|
||||||
|
|
||||||
20-10-2002: DarkIce 0.12 released
|
|
||||||
|
|
||||||
o ported to FreeBSD (removed reference to MSG_NOSIGNAL in TcpSocket.cpp)
|
|
||||||
o bug fix: maximum bitrate setting fixed for Ogg Vorbis streams
|
|
||||||
o changed internals so that now each encoding/server connection is
|
|
||||||
a separate thread
|
|
||||||
o when a connection is dropped, DarkIce tries to reconnect, indefinitely
|
|
||||||
|
|
||||||
20-08-2002: DarkIce 0.11 released
|
|
||||||
|
|
||||||
o added possibility to specify maximum bitrate for Ogg Vorbis streams
|
|
||||||
o added HTTP Basic authentication for icecast2 logins
|
|
||||||
o added mp3 streaming for icecast2
|
|
||||||
o added possibility to stream in mono even when recording in stereo,
|
|
||||||
thus enabling mono and stereo streams with the same darkice instance.
|
|
||||||
only for mp3 streams at the moment
|
|
||||||
thanks to Kai Krakow <kai@kaishome.de>
|
|
||||||
o bug fix: resampling audio for vorbis streams bugs fixed
|
|
||||||
|
|
||||||
02-08-2002: DarkIce 0.10.1 released
|
|
||||||
|
|
||||||
o bug fix: when the last server dropped connection, darkice crashed
|
|
||||||
thanks to Nicu Pavel <npavel@ituner.com>
|
|
||||||
o bug fix for LameLibEncoder: the mp3 encoding buffer was deleted too
|
|
||||||
early, resulting in mp3 data corruption.
|
|
||||||
thanks to Nicu Pavel <npavel@ituner.com>
|
|
||||||
|
|
||||||
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 <npavel@ituner.com>
|
|
||||||
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 <kgb@gangverk.is> and Nicu Pavel <npavel@ituner.com>
|
|
||||||
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, <jos@ccrma.stanford.edu> 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, <tomg@future-i.com>
|
|
||||||
o made up-to-date with Ogg Vorbis rc3 libs
|
|
||||||
thanks to Michael Smith, <msmith@labyrinth.net.au>
|
|
||||||
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, <Robin_Blanchard@gactr.uga.edu>
|
|
||||||
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 <analogue@glop.org>
|
|
||||||
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, <JCrilly@MSA.com>
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
DarkIce Frequenty Asked Questions
|
|
||||||
|
|
||||||
|
|
||||||
Q: I get the following error:
|
|
||||||
|
|
||||||
DarkIce: LameLibEncoder.cpp:75: lame lib opening underlying sink error [0]
|
|
||||||
|
|
||||||
What am I doing wrong?
|
|
||||||
|
|
||||||
|
|
||||||
A: This error means (quite anti-intuitively), that darkice coulnd't connect
|
|
||||||
to the streaming server. Please double-check the following values in
|
|
||||||
your config file:
|
|
||||||
- server
|
|
||||||
- port
|
|
||||||
- password
|
|
||||||
|
|
||||||
If you're streaming to a shoutcast server, make sure that the port
|
|
||||||
you use is the _source_ port, which is usually 1 above the _client_
|
|
||||||
port for shoutcast (the defaults are 8000 for client, 8001 for source).
|
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
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
|
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
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
|
|
||||||
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
Installing Ogg Vorbis
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
To install DarkIce, you need the following Ogg Vorbis 1.0 or later
|
|
||||||
libraries (and related header files):
|
|
||||||
|
|
||||||
- libogg
|
|
||||||
- libvoribs
|
|
||||||
- libvorbisenc
|
|
||||||
|
|
||||||
installed on your system.
|
|
||||||
|
|
||||||
It is recommended that use install these to the usual system locations,
|
|
||||||
/usr/lib, /usr/include, so that DarkIce will find the header files and
|
|
||||||
libraries. Thus when configuring, add --prefix=/usr to the configure
|
|
||||||
options.
|
|
||||||
|
|
||||||
Grab the latest Ogg Vorbis tarballs from
|
|
||||||
http://www.xiph.org/ogg/vorbis/download.html
|
|
||||||
|
|
||||||
I took libogg-1.0.tar.gz and libvorbis-1.0.tar.gz. Go to the
|
|
||||||
directory where you saved them, and issue the following commands:
|
|
||||||
|
|
||||||
tar xfz libogg-1.0.tar.gz
|
|
||||||
cd libogg-1.0
|
|
||||||
./configure --prefix=/usr
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
tar xfz libvorbis-1.0.tar.gz
|
|
||||||
cd libvorbis-1.0
|
|
||||||
./configure --prefix=/usr
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
|
|
||||||
For the install steps, you need to be root or have write permissions in the
|
|
||||||
target directories.
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
DOC_DIR = doc
|
|
||||||
DOXYGEN_DIR = doc/doxygen
|
|
||||||
DOXYGEN_CONFIG = etc/doxygen.config
|
|
||||||
|
|
||||||
SUBDIRS = src man
|
|
||||||
|
|
||||||
sysconf_DATA = darkice.cfg
|
|
||||||
|
|
||||||
EXTRA_DIST = $(DOC_DIR) darkice.cfg INSTALL.lame INSTALL.vorbis FAQ
|
|
||||||
|
|
||||||
.PHONY: doc
|
|
||||||
|
|
||||||
doc: src
|
|
||||||
# mkdir -p $(DOXYGEN_DIR)
|
|
||||||
# doxygen etc/doxygen.config
|
|
||||||
|
|
||||||
doxygen_clean:
|
|
||||||
rm -rf $(DOXYGEN_DIR)
|
|
||||||
|
|
|
@ -1,128 +0,0 @@
|
||||||
07-07-2008, Akos Maroy, darkeye@tyrell.hu
|
|
||||||
|
|
||||||
Released version 0.19. See ChangeLog for changes.
|
|
||||||
|
|
||||||
26-04-2007, Akos Maroy, darkeye@tyrell.hu
|
|
||||||
|
|
||||||
Released version 0.18.1. See ChangeLog for changes.
|
|
||||||
|
|
||||||
05-03-2007, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.18. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
19-05-2006, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.17.1. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
26-01-2006, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.17. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
22-10-2005, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.16. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
14-04-2005, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.15. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
15-02-2004, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.14. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
07-01-2004, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.13.2. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
12-02-2003, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.13.1. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
09-02-2003, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.13. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
20-10-2002, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.12. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
20-08-2002, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.11. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
02-08-2002, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.10.1. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
20-07-2002, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.10. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
09-04-2002, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.9.1. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
28-03-2002, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.9. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
20-02-2002, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.8. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
19-10-2001, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.7. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
18-09-2001, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.6. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
09-09-2001, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.5. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
02-09-2001, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.4. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
26-08-2001, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.3.1. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
20-12-2000, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.3. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
18-11-2000, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Released version 0.2. See ChangeLog for changes.
|
|
||||||
|
|
||||||
|
|
||||||
13-11-2000, Akos Maroy, darkeye@users.sourceforge.net
|
|
||||||
|
|
||||||
Initial release. Supports the lame encoder.
|
|
||||||
|
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
DarkIce live audio streamer, http://darkice.tyrell.hu/
|
|
||||||
Copyright (c) 2000-2007, Tyrell Hungary, http://tyrell.hu/
|
|
||||||
|
|
||||||
|
|
||||||
Contents
|
|
||||||
--------
|
|
||||||
|
|
||||||
1. What is DarkIce?
|
|
||||||
2. Compiling and installing
|
|
||||||
3. Reporting crashes
|
|
||||||
|
|
||||||
|
|
||||||
1. What is DarkIce?
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
DarkIce is an IceCast, IceCast2 and ShoutCast live audio streamer. It
|
|
||||||
takes audio input from a sound card, encodes it into mp3 and/or Ogg Vorbis,
|
|
||||||
and sends the mp3 stream to one or more IceCast and/or ShoutCast servers,
|
|
||||||
the Ogg Vorbis stream to one or more IceCast2 servers.
|
|
||||||
|
|
||||||
DarkIce is hosted by Tyrell Corporation, at http://darkice.tyrell.hu/
|
|
||||||
|
|
||||||
|
|
||||||
2. Compiling and installing
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
On how to compile and install, please read the file INSTALL. If you're
|
|
||||||
impatient, try:
|
|
||||||
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
|
|
||||||
The executable built is src/darkice.
|
|
||||||
To install, try as root:
|
|
||||||
|
|
||||||
make install
|
|
||||||
|
|
||||||
|
|
||||||
For documentation, try:
|
|
||||||
|
|
||||||
man darkice
|
|
||||||
|
|
||||||
|
|
||||||
3. Reporting crashes
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
When DarkIce core dumps, please send the backtrace along with your error
|
|
||||||
report to the darkice mailing list: darkice-list@lists.tyrell.hu.
|
|
||||||
Alternatively you could file a bug report at http://darkice.tyrell.hu/trac
|
|
||||||
To get the backtrace information, you need gdb, the GNU debugger:
|
|
||||||
|
|
||||||
1. configure and compile using the --with-debug option:
|
|
||||||
|
|
||||||
./configure --with-debug=yes
|
|
||||||
make clean all
|
|
||||||
|
|
||||||
2. run darkice from within gdb:
|
|
||||||
|
|
||||||
gdb src/darkice
|
|
||||||
|
|
||||||
3. set parameters within gdb:
|
|
||||||
|
|
||||||
(gdb) set args -c darkice.cfg
|
|
||||||
|
|
||||||
4. run:
|
|
||||||
|
|
||||||
(gdb) run
|
|
||||||
|
|
||||||
5. after coredump, print the backtrace:
|
|
||||||
|
|
||||||
(gdb) bt
|
|
||||||
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
o change Ref to follow inheritance
|
|
||||||
o make a master config file, and a small one ?
|
|
||||||
o add support for multiple servers for one stream ?
|
|
||||||
o revisit real-time scheduling
|
|
||||||
o look into performance
|
|
||||||
o create proper error-reporting module
|
|
||||||
o set comment fields for Ogg Vorbis streams as in
|
|
||||||
http://www.xiph.org/ogg/vorbis/doc/v-comment.html
|
|
||||||
o change config file to separate descriptions of input, streams and
|
|
||||||
stream targets (servers, files, etc.)
|
|
||||||
o add support for 24 and 32 bit input and higher sample rates (up to 96kHz)
|
|
|
@ -1,299 +0,0 @@
|
||||||
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/lib64 $5/lib )
|
|
||||||
dnl look for header.
|
|
||||||
LA_SEARCH_FILE($2, $4, $5 $5/include )
|
|
||||||
if test ".$1" = "." || test ".$2" = "."; then
|
|
||||||
$1=
|
|
||||||
$2=
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
dnl funky posix threads checking, thanks to
|
|
||||||
dnl Steven G. Johnson <stevenj@alum.mit.edu>
|
|
||||||
dnl and Alejandro Forero Cuervo <bachue@bachue.com>
|
|
||||||
dnl see http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
|
|
||||||
dnl
|
|
||||||
dnl This macro figures out how to build C programs using POSIX
|
|
||||||
dnl threads. It sets the PTHREAD_LIBS output variable to the threads
|
|
||||||
dnl library and linker flags, and the PTHREAD_CFLAGS output variable
|
|
||||||
dnl to any special C compiler flags that are needed. (The user can also
|
|
||||||
dnl force certain compiler flags/libs to be tested by setting these
|
|
||||||
dnl environment variables.)
|
|
||||||
dnl
|
|
||||||
dnl Also sets PTHREAD_CC to any special C compiler that is needed for
|
|
||||||
dnl multi-threaded programs (defaults to the value of CC otherwise).
|
|
||||||
dnl (This is necessary on AIX to use the special cc_r compiler alias.)
|
|
||||||
dnl
|
|
||||||
dnl NOTE: You are assumed to not only compile your program with these
|
|
||||||
dnl flags, but also link it with them as well. e.g. you should link
|
|
||||||
dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
|
|
||||||
dnl
|
|
||||||
dnl If you are only building threads programs, you may wish to
|
|
||||||
dnl use these variables in your default LIBS, CFLAGS, and CC:
|
|
||||||
dnl
|
|
||||||
dnl LIBS="$PTHREAD_LIBS $LIBS"
|
|
||||||
dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
|
||||||
dnl CC="$PTHREAD_CC"
|
|
||||||
dnl
|
|
||||||
dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
|
|
||||||
dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE
|
|
||||||
dnl to that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
|
|
||||||
dnl
|
|
||||||
dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
|
|
||||||
dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands
|
|
||||||
dnl to run it if it is not found. If ACTION-IF-FOUND is not specified,
|
|
||||||
dnl the default action will define HAVE_PTHREAD.
|
|
||||||
dnl
|
|
||||||
dnl Please let the authors know if this macro fails on any platform,
|
|
||||||
dnl or if you have any other suggestions or comments. This macro was
|
|
||||||
dnl based on work by SGJ on autoconf scripts for FFTW (www.fftw.org)
|
|
||||||
dnl (with help from M. Frigo), as well as ac_pthread and hb_pthread
|
|
||||||
dnl macros posted by AFC to the autoconf macro repository. We are also
|
|
||||||
dnl grateful for the helpful feedback of numerous users.
|
|
||||||
dnl
|
|
||||||
dnl @version $Id$
|
|
||||||
dnl @author Steven G. Johnson <stevenj@alum.mit.edu> and Alejandro Forero Cuervo <bachue@bachue.com>
|
|
||||||
|
|
||||||
AC_DEFUN([ACX_PTHREAD], [
|
|
||||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
|
||||||
AC_LANG_SAVE
|
|
||||||
AC_LANG_C
|
|
||||||
acx_pthread_ok=no
|
|
||||||
|
|
||||||
# We used to check for pthread.h first, but this fails if pthread.h
|
|
||||||
# requires special compiler flags (e.g. on True64 or Sequent).
|
|
||||||
# It gets checked for in the link test anyway.
|
|
||||||
|
|
||||||
# First of all, check if the user has set any of the PTHREAD_LIBS,
|
|
||||||
# etcetera environment variables, and if threads linking works using
|
|
||||||
# them:
|
|
||||||
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
|
|
||||||
save_CFLAGS="$CFLAGS"
|
|
||||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
|
||||||
save_LIBS="$LIBS"
|
|
||||||
LIBS="$PTHREAD_LIBS $LIBS"
|
|
||||||
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
|
|
||||||
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
|
|
||||||
AC_MSG_RESULT($acx_pthread_ok)
|
|
||||||
if test x"$acx_pthread_ok" = xno; then
|
|
||||||
PTHREAD_LIBS=""
|
|
||||||
PTHREAD_CFLAGS=""
|
|
||||||
fi
|
|
||||||
LIBS="$save_LIBS"
|
|
||||||
CFLAGS="$save_CFLAGS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# We must check for the threads library under a number of different
|
|
||||||
# names; the ordering is very important because some systems
|
|
||||||
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
|
|
||||||
# libraries is broken (non-POSIX).
|
|
||||||
|
|
||||||
# Create a list of thread flags to try. Items starting with a "-" are
|
|
||||||
# C compiler flags, and other items are library names, except for "none"
|
|
||||||
# which indicates that we try without any flags at all.
|
|
||||||
|
|
||||||
acx_pthread_flags="pthread-config pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt"
|
|
||||||
|
|
||||||
# The ordering *is* (sometimes) important. Some notes on the
|
|
||||||
# individual items follow:
|
|
||||||
|
|
||||||
# pthread-config: use pthread-config program (on NetBSD)
|
|
||||||
# pthreads: AIX (must check this before -lpthread)
|
|
||||||
# none: in case threads are in libc; should be tried before -Kthread and
|
|
||||||
# other compiler flags to prevent continual compiler warnings
|
|
||||||
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
|
|
||||||
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
|
|
||||||
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
|
|
||||||
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
|
|
||||||
# -pthreads: Solaris/gcc
|
|
||||||
# -mthreads: Mingw32/gcc, Lynx/gcc
|
|
||||||
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
|
|
||||||
# doesn't hurt to check since this sometimes defines pthreads too;
|
|
||||||
# also defines -D_REENTRANT)
|
|
||||||
# pthread: Linux, etcetera
|
|
||||||
# --thread-safe: KAI C++
|
|
||||||
|
|
||||||
case "${host_cpu}-${host_os}" in
|
|
||||||
*solaris*)
|
|
||||||
|
|
||||||
# On Solaris (at least, for some versions), libc contains stubbed
|
|
||||||
# (non-functional) versions of the pthreads routines, so link-based
|
|
||||||
# tests will erroneously succeed. (We need to link with -pthread or
|
|
||||||
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
|
|
||||||
# a function called by this macro, so we could check for that, but
|
|
||||||
# who knows whether they'll stub that too in a future libc.) So,
|
|
||||||
# we'll just look for -pthreads and -lpthread first:
|
|
||||||
|
|
||||||
acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if test x"$acx_pthread_ok" = xno; then
|
|
||||||
for flag in $acx_pthread_flags; do
|
|
||||||
|
|
||||||
case $flag in
|
|
||||||
none)
|
|
||||||
AC_MSG_CHECKING([whether pthreads work without any flags])
|
|
||||||
;;
|
|
||||||
|
|
||||||
-*)
|
|
||||||
AC_MSG_CHECKING([whether pthreads work with $flag])
|
|
||||||
PTHREAD_CFLAGS="$flag"
|
|
||||||
;;
|
|
||||||
|
|
||||||
pthread-config)
|
|
||||||
AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
|
|
||||||
if test x"$acx_pthread_config" = xno; then continue; fi
|
|
||||||
PTHREAD_CFLAGS="`pthread-config --cflags`"
|
|
||||||
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
AC_MSG_CHECKING([for the pthreads library -l$flag])
|
|
||||||
PTHREAD_LIBS="-l$flag"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
save_LIBS="$LIBS"
|
|
||||||
save_CFLAGS="$CFLAGS"
|
|
||||||
LIBS="$PTHREAD_LIBS $LIBS"
|
|
||||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
|
||||||
|
|
||||||
# Check for various functions. We must include pthread.h,
|
|
||||||
# since some functions may be macros. (On the Sequent, we
|
|
||||||
# need a special flag -Kthread to make this header compile.)
|
|
||||||
# We check for pthread_join because it is in -lpthread on IRIX
|
|
||||||
# while pthread_create is in libc. We check for pthread_attr_init
|
|
||||||
# due to DEC craziness with -lpthreads. We check for
|
|
||||||
# pthread_cleanup_push because it is one of the few pthread
|
|
||||||
# functions on Solaris that doesn't have a non-functional libc stub.
|
|
||||||
# We try pthread_create on general principles.
|
|
||||||
AC_TRY_LINK([#include <pthread.h>],
|
|
||||||
[pthread_t th; pthread_join(th, 0);
|
|
||||||
pthread_attr_init(0); pthread_cleanup_push(0, 0);
|
|
||||||
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
|
|
||||||
[acx_pthread_ok=yes])
|
|
||||||
|
|
||||||
LIBS="$save_LIBS"
|
|
||||||
CFLAGS="$save_CFLAGS"
|
|
||||||
|
|
||||||
AC_MSG_RESULT($acx_pthread_ok)
|
|
||||||
if test "x$acx_pthread_ok" = xyes; then
|
|
||||||
break;
|
|
||||||
fi
|
|
||||||
|
|
||||||
PTHREAD_LIBS=""
|
|
||||||
PTHREAD_CFLAGS=""
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Various other checks:
|
|
||||||
if test "x$acx_pthread_ok" = xyes; then
|
|
||||||
save_LIBS="$LIBS"
|
|
||||||
LIBS="$PTHREAD_LIBS $LIBS"
|
|
||||||
save_CFLAGS="$CFLAGS"
|
|
||||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
|
||||||
|
|
||||||
# Detect AIX lossage: threads are created detached by default
|
|
||||||
# and the JOINABLE attribute has a nonstandard name (UNDETACHED).
|
|
||||||
AC_MSG_CHECKING([for joinable pthread attribute])
|
|
||||||
AC_TRY_LINK([#include <pthread.h>],
|
|
||||||
[int attr=PTHREAD_CREATE_JOINABLE;],
|
|
||||||
ok=PTHREAD_CREATE_JOINABLE, ok=unknown)
|
|
||||||
if test x"$ok" = xunknown; then
|
|
||||||
AC_TRY_LINK([#include <pthread.h>],
|
|
||||||
[int attr=PTHREAD_CREATE_UNDETACHED;],
|
|
||||||
ok=PTHREAD_CREATE_UNDETACHED, ok=unknown)
|
|
||||||
fi
|
|
||||||
if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then
|
|
||||||
AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok,
|
|
||||||
[Define to the necessary symbol if this constant
|
|
||||||
uses a non-standard name on your system.])
|
|
||||||
fi
|
|
||||||
AC_MSG_RESULT(${ok})
|
|
||||||
if test x"$ok" = xunknown; then
|
|
||||||
AC_MSG_WARN([we do not know how to create joinable pthreads])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([if more special flags are required for pthreads])
|
|
||||||
flag=no
|
|
||||||
case "${host_cpu}-${host_os}" in
|
|
||||||
*-aix* | *-freebsd*) flag="-D_THREAD_SAFE";;
|
|
||||||
*solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
|
|
||||||
esac
|
|
||||||
AC_MSG_RESULT(${flag})
|
|
||||||
if test "x$flag" != xno; then
|
|
||||||
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
LIBS="$save_LIBS"
|
|
||||||
CFLAGS="$save_CFLAGS"
|
|
||||||
|
|
||||||
# More AIX lossage: must compile with cc_r
|
|
||||||
AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC})
|
|
||||||
else
|
|
||||||
PTHREAD_CC="$CC"
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_SUBST(PTHREAD_LIBS)
|
|
||||||
AC_SUBST(PTHREAD_CFLAGS)
|
|
||||||
AC_SUBST(PTHREAD_CC)
|
|
||||||
|
|
||||||
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
|
|
||||||
if test x"$acx_pthread_ok" = xyes; then
|
|
||||||
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
|
|
||||||
:
|
|
||||||
else
|
|
||||||
acx_pthread_ok=no
|
|
||||||
$2
|
|
||||||
fi
|
|
||||||
AC_LANG_RESTORE
|
|
||||||
])dnl ACX_PTHREAD
|
|
|
@ -1,69 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# Run this to set up the build system: configure, makefiles, etc.
|
|
||||||
# (based on the version in enlightenment's cvs)
|
|
||||||
|
|
||||||
package="darkice"
|
|
||||||
|
|
||||||
srcdir=`dirname $0`
|
|
||||||
test -z "$srcdir" && srcdir=.
|
|
||||||
|
|
||||||
cd "$srcdir"
|
|
||||||
DIE=0
|
|
||||||
|
|
||||||
(autoheader --version) < /dev/null > /dev/null 2>&1 || {
|
|
||||||
echo
|
|
||||||
echo "You must have autoconf installed to compile $package."
|
|
||||||
echo "Download the appropriate package for your distribution,"
|
|
||||||
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
|
||||||
DIE=1
|
|
||||||
}
|
|
||||||
|
|
||||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
|
||||||
echo
|
|
||||||
echo "You must have autoconf installed to compile $package."
|
|
||||||
echo "Download the appropriate package for your distribution,"
|
|
||||||
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
|
||||||
DIE=1
|
|
||||||
}
|
|
||||||
|
|
||||||
(automake --version) < /dev/null > /dev/null 2>&1 || {
|
|
||||||
echo
|
|
||||||
echo "You must have automake installed to compile $package."
|
|
||||||
echo "Download the appropriate package for your system,"
|
|
||||||
echo "or get the source from one of the GNU ftp sites"
|
|
||||||
echo "listed in http://www.gnu.org/order/ftp.html"
|
|
||||||
DIE=1
|
|
||||||
}
|
|
||||||
|
|
||||||
(libtool --help) < /dev/null > /dev/null 2>&1 || {
|
|
||||||
echo
|
|
||||||
echo "You must have libtool installed to compile $package."
|
|
||||||
echo "Download the appropriate package for your system,"
|
|
||||||
echo "or get the source from one of the GNU ftp sites"
|
|
||||||
echo "listed in http://www.gnu.org/order/ftp.html"
|
|
||||||
DIE=1
|
|
||||||
}
|
|
||||||
|
|
||||||
if test "$DIE" -eq 1; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -z "$*"; then
|
|
||||||
echo "I am going to run ./configure with no arguments - if you wish "
|
|
||||||
echo "to pass any to it, please specify them on the $0 command line."
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Generating configuration files for $package, please wait...."
|
|
||||||
|
|
||||||
echo " aclocal $ACLOCAL_FLAGS"
|
|
||||||
aclocal $ACLOCAL_FLAGS
|
|
||||||
echo " autoheader"
|
|
||||||
autoheader
|
|
||||||
echo " libtoolize --automake"
|
|
||||||
libtoolize --automake
|
|
||||||
echo " automake --add-missing $AUTOMAKE_FLAGS"
|
|
||||||
automake --add-missing $AUTOMAKE_FLAGS
|
|
||||||
echo " autoconf"
|
|
||||||
autoconf
|
|
||||||
|
|
||||||
$srcdir/configure "$@" && echo
|
|
|
@ -1,344 +0,0 @@
|
||||||
dnl Process this file with autoconf to produce a configure script.
|
|
||||||
AC_INIT(darkice, 0.19)
|
|
||||||
AC_CONFIG_SRCDIR(src/DarkIce.cpp)
|
|
||||||
AM_CONFIG_HEADER(src/config.h)
|
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE
|
|
||||||
|
|
||||||
AC_PROG_CC
|
|
||||||
AC_PROG_CXX
|
|
||||||
AC_PROG_INSTALL
|
|
||||||
|
|
||||||
dnl AC_STDC_HEADERS
|
|
||||||
AC_HAVE_HEADERS(errno.h fcntl.h stdio.h stdlib.h string.h unistd.h limits.h)
|
|
||||||
AC_HAVE_HEADERS(signal.h time.h sys/time.h sys/types.h sys/wait.h math.h)
|
|
||||||
AC_HAVE_HEADERS(netdb.h netinet/in.h sys/ioctl.h sys/socket.h sys/stat.h)
|
|
||||||
AC_HAVE_HEADERS(sched.h pthread.h termios.h)
|
|
||||||
AC_HAVE_HEADERS(sys/soundcard.h sys/audio.h sys/audioio.h)
|
|
||||||
AC_HEADER_SYS_WAIT()
|
|
||||||
|
|
||||||
AC_TYPE_PID_T()
|
|
||||||
AC_TYPE_SIZE_T()
|
|
||||||
AC_C_BIGENDIAN()
|
|
||||||
|
|
||||||
AC_CHECK_LIB(socket, socket)
|
|
||||||
AC_CHECK_LIB(nsl, gethostbyname)
|
|
||||||
AC_CHECK_LIB(rt, sched_getscheduler)
|
|
||||||
|
|
||||||
AC_CHECK_FUNC(getaddrinfo, AC_DEFINE(HAVE_GETADDRINFO, 1, [Does function getaddrinfo exist?] ))
|
|
||||||
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
dnl funky posix threads checking, thanks to
|
|
||||||
dnl Steven G. Johnson <stevenj@alum.mit.edu>
|
|
||||||
dnl and Alejandro Forero Cuervo <bachue@bachue.com>
|
|
||||||
dnl see http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
ACX_PTHREAD(, AC_MSG_ERROR( [pthread library not found] ))
|
|
||||||
|
|
||||||
SYSTEM_INCLUDE=/usr/include
|
|
||||||
|
|
||||||
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
dnl link the lame library if requested
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
AC_SUBST(LAME_INCFLAGS)
|
|
||||||
AC_SUBST(LAME_LDFLAGS)
|
|
||||||
|
|
||||||
AC_ARG_WITH(lame,
|
|
||||||
[ --with-lame use lame for encoding mp3 streams [yes] ],
|
|
||||||
USE_LAME=${withval}, USE_LAME="yes" )
|
|
||||||
AC_ARG_WITH(lame-prefix,
|
|
||||||
[ --with-lame-prefix=DIR alternate location for lame [/usr]
|
|
||||||
look for libraries in LAME-PREFIX/lib,
|
|
||||||
for headers in LAME-PREFIX/include],
|
|
||||||
CONFIG_LAME_PREFIX="${withval}", CONFIG_LAME_PREFIX="/usr")
|
|
||||||
|
|
||||||
if test "x${USE_LAME}" = "xyes" ; then
|
|
||||||
AC_MSG_CHECKING( [for lame library at ${CONFIG_LAME_PREFIX}] )
|
|
||||||
LA_SEARCH_LIB( LAME_LIB_LOC, LAME_INC_LOC, libmp3lame.a libmp3lame.so, 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 libogg.so, ogg/ogg.h,
|
|
||||||
${CONFIG_VORBIS_PREFIX})
|
|
||||||
LA_SEARCH_LIB( VORBIS_LIB_LOC, VORBIS_INC_LOC, libvorbis.a libvorbis.so, vorbis/codec.h,
|
|
||||||
${CONFIG_VORBIS_PREFIX})
|
|
||||||
LA_SEARCH_LIB( VORBISENC_LIB_LOC, VORBISENC_INC_LOC,
|
|
||||||
libvorbisenc.a libvorbisenc.so, vorbis/vorbisenc.h,
|
|
||||||
${CONFIG_VORBIS_PREFIX})
|
|
||||||
|
|
||||||
if test "x${OGG_LIB_LOC}" != "x" -a \
|
|
||||||
"x${VORBIS_LIB_LOC}" != "x" -a \
|
|
||||||
"x${VORBISENC_LIB_LOC}" != "x" ; then
|
|
||||||
|
|
||||||
AC_DEFINE( HAVE_VORBIS_LIB, 1, [build with Ogg Vorbis library] )
|
|
||||||
if test "x${OGG_INC_LOC}" != "x${SYSTEM_INCLUDE}" ; then
|
|
||||||
VORBIS_INCFLAGS="-I${OGG_INC_LOC}"
|
|
||||||
fi
|
|
||||||
VORBIS_LDFLAGS="-L${OGG_LIB_LOC} -logg -lvorbis -lvorbisenc"
|
|
||||||
AC_MSG_RESULT( [found at ${CONFIG_VORBIS_PREFIX}] )
|
|
||||||
else
|
|
||||||
AC_MSG_WARN( [not found, building without Ogg Vorbis])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT( [building without Ogg Vorbis] )
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
dnl link the faac library if requested
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
AC_SUBST(FAAC_INCFLAGS)
|
|
||||||
AC_SUBST(FAAC_LDFLAGS)
|
|
||||||
|
|
||||||
AC_ARG_WITH(faac,
|
|
||||||
[ --with-faac use faac for encoding AAC streams [yes] ],
|
|
||||||
USE_FAAC=${withval}, USE_FAAC="yes" )
|
|
||||||
AC_ARG_WITH(faac-prefix,
|
|
||||||
[ --with-faac-prefix=DIR alternate location for faac [/usr]
|
|
||||||
look for libraries in FAAC-PREFIX/lib,
|
|
||||||
for headers in FAAC-PREFIX/include],
|
|
||||||
CONFIG_FAAC_PREFIX="${withval}", CONFIG_FAAC_PREFIX="/usr")
|
|
||||||
|
|
||||||
if test "x${USE_FAAC}" = "xyes" ; then
|
|
||||||
AC_MSG_CHECKING( [for faac library at ${CONFIG_FAAC_PREFIX}] )
|
|
||||||
LA_SEARCH_LIB( FAAC_LIB_LOC, FAAC_INC_LOC, libfaac.a libfaac.so, faac.h,
|
|
||||||
${CONFIG_FAAC_PREFIX})
|
|
||||||
if test "x${FAAC_LIB_LOC}" != "x" ; then
|
|
||||||
AC_DEFINE( HAVE_FAAC_LIB, 1, [build with faac library] )
|
|
||||||
if test "x${FAAC_INC_LOC}" != "x${SYSTEM_INCLUDE}" ; then
|
|
||||||
FAAC_INCFLAGS="-I${FAAC_INC_LOC}"
|
|
||||||
fi
|
|
||||||
FAAC_LDFLAGS="-L${FAAC_LIB_LOC} -lfaac"
|
|
||||||
AC_MSG_RESULT( [found at ${CONFIG_FAAC_PREFIX}] )
|
|
||||||
else
|
|
||||||
AC_MSG_WARN( [not found, building without faac])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT( [building without faac] )
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
dnl link the aacplus library if requested
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
AC_SUBST(AACPLUS_INCFLAGS)
|
|
||||||
AC_SUBST(AACPLUS_LDFLAGS)
|
|
||||||
|
|
||||||
AC_ARG_WITH(aacplus,
|
|
||||||
[ --with-aacplus use aacplus for encoding AAC HEv2 streams [yes] ],
|
|
||||||
USE_AACPLUS=${withval}, USE_AACPLUS="yes" )
|
|
||||||
AC_ARG_WITH(aacplus-prefix,
|
|
||||||
[ --with-aacplus-prefix=DIR alternate location for aacplus [/usr]
|
|
||||||
look for libraries in AACPLUS-PREFIX/lib,
|
|
||||||
for headers in AACPLUS-PREFIX/include],
|
|
||||||
CONFIG_AACPLUS_PREFIX="${withval}", CONFIG_AACPLUS_PREFIX="/usr")
|
|
||||||
|
|
||||||
if test "x${USE_AACPLUS}" = "xyes" ; then
|
|
||||||
AC_MSG_CHECKING( [for aacplus library at ${CONFIG_AACPLUS_PREFIX}] )
|
|
||||||
LA_SEARCH_LIB( AACPLUS_LIB_LOC, AACPLUS_INC_LOC, libaacplus.a libaacplus.so, sbr_main.h,
|
|
||||||
${CONFIG_AACPLUS_PREFIX})
|
|
||||||
if test "x${AACPLUS_LIB_LOC}" != "x" ; then
|
|
||||||
AC_DEFINE( HAVE_AACPLUS_LIB, 1, [build with aacplus library] )
|
|
||||||
if test "x${AACPLUS_INC_LOC}" != "x${SYSTEM_INCLUDE}" ; then
|
|
||||||
AACPLUS_INCFLAGS="-I${AACPLUS_INC_LOC}"
|
|
||||||
fi
|
|
||||||
AACPLUS_LDFLAGS="-L${AACPLUS_LIB_LOC} -laacplus"
|
|
||||||
AC_MSG_RESULT( [found at ${CONFIG_AACPLUS_PREFIX}] )
|
|
||||||
else
|
|
||||||
AC_MSG_WARN( [not found, building without aacplus])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT( [building without aacplus] )
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
dnl link the twolame library if requested
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
AC_SUBST(TWOLAME_INCFLAGS)
|
|
||||||
AC_SUBST(TWOLAME_LDFLAGS)
|
|
||||||
|
|
||||||
AC_ARG_WITH(twolame,
|
|
||||||
[ --with-twolame use twolame for encoding MP2 streams [yes] ],
|
|
||||||
USE_TWOLAME=${withval}, USE_TWOLAME="yes" )
|
|
||||||
AC_ARG_WITH(twolame-prefix,
|
|
||||||
[ --with-twolame-prefix=DIR alternate location for twolame [/usr]
|
|
||||||
look for libraries in TWOLAME-PREFIX/lib,
|
|
||||||
for headers in TWOLAME-PREFIX/include],
|
|
||||||
CONFIG_TWOLAME_PREFIX="${withval}", CONFIG_TWOLAME_PREFIX="/usr")
|
|
||||||
|
|
||||||
if test "x${USE_TWOLAME}" = "xyes" ; then
|
|
||||||
AC_MSG_CHECKING( [for twolame library at ${CONFIG_TWOLAME_PREFIX}] )
|
|
||||||
LA_SEARCH_LIB( TWOLAME_LIB_LOC, TWOLAME_INC_LOC, libtwolame.a libtwolame.so, twolame.h,
|
|
||||||
${CONFIG_TWOLAME_PREFIX})
|
|
||||||
if test "x${TWOLAME_LIB_LOC}" != "x" ; then
|
|
||||||
AC_DEFINE( HAVE_TWOLAME_LIB, 1, [build with twolame library] )
|
|
||||||
if test "x${TWOLAME_INC_LOC}" != "x${SYSTEM_INCLUDE}" ; then
|
|
||||||
TWOLAME_INCFLAGS="-I${TWOLAME_INC_LOC}"
|
|
||||||
fi
|
|
||||||
TWOLAME_LDFLAGS="-L${TWOLAME_LIB_LOC} -ltwolame"
|
|
||||||
AC_MSG_RESULT( [found at ${CONFIG_TWOLAME_PREFIX}] )
|
|
||||||
else
|
|
||||||
AC_MSG_WARN( [not found, building without twolame])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT( [building without twolame] )
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
dnl make sure at least one of lame and vorbis present
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
if test "x${LAME_LDFLAGS}" = "x" \
|
|
||||||
-a "x${VORBIS_LDFLAGS}" = "x" \
|
|
||||||
-a "x${FAAC_LDFLAGS}" = "x" \
|
|
||||||
-a "x${AACPLUS_LDFLAGS}" = "x" \
|
|
||||||
-a "x${TWOLAME_LDFLAGS}" = "x"; then
|
|
||||||
AC_MSG_ERROR([neither lame, Ogg Vorbis, faac, aac+ nor twolame configured])
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
dnl link ALSA sound system if requested
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
AC_SUBST(ALSA_INCFLAGS)
|
|
||||||
AC_SUBST(ALSA_LDFLAGS)
|
|
||||||
|
|
||||||
AC_ARG_WITH(alsa,
|
|
||||||
[ --with-alsa use ALSA sound system [yes] ],
|
|
||||||
USE_ALSA=${withval}, USE_ALSA="yes" )
|
|
||||||
AC_ARG_WITH(alsa-prefix,
|
|
||||||
[ --with-alsa-prefix=DIR alternate location for ALSA [/usr]
|
|
||||||
look for libraries in ALSA-PREFIX/lib,
|
|
||||||
for headers in ALSA-PREFIX/include],
|
|
||||||
CONFIG_ALSA_PREFIX="${withval}", CONFIG_ALSA_PREFIX="/usr")
|
|
||||||
|
|
||||||
if test "x${USE_ALSA}" = "xyes" ; then
|
|
||||||
AC_MSG_CHECKING( [for alsa libraries at ${CONFIG_ALSA_PREFIX}] )
|
|
||||||
LA_SEARCH_LIB( ALSA_LIB_LOC, ALSA_INC_LOC, libasound.so, alsa/asoundlib.h,
|
|
||||||
${CONFIG_ALSA_PREFIX})
|
|
||||||
|
|
||||||
if test "x${ALSA_LIB_LOC}" != "x" ; then
|
|
||||||
|
|
||||||
AC_DEFINE( HAVE_ALSA_LIB, 1, [build with ALSA sound system] )
|
|
||||||
if test "x${ALSA_INC_LOC}" != "x${SYSTEM_INCLUDE}" ; then
|
|
||||||
ALSA_INCFLAGS="-I${ALSA_INC_LOC}"
|
|
||||||
fi
|
|
||||||
ALSA_LDFLAGS="-L${ALSA_LIB_LOC} -lasound"
|
|
||||||
AC_MSG_RESULT( [found at ${CONFIG_ALSA_PREFIX}] )
|
|
||||||
else
|
|
||||||
AC_MSG_WARN( [not found, building without ALSA support])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT( [building without ALSA support] )
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
dnl link JACK sound server if requested
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
AC_SUBST(JACK_CFLAGS)
|
|
||||||
AC_SUBST(JACK_LDFLAGS)
|
|
||||||
|
|
||||||
AC_ARG_WITH(jack,
|
|
||||||
[ --with-jack use JACK sound system [yes] ],
|
|
||||||
USE_JACK=${withval}, USE_JACK="yes" )
|
|
||||||
AC_ARG_WITH(jack-prefix,
|
|
||||||
[ --with-jack-prefix=DIR alternate location for JACK [/usr]
|
|
||||||
look for libraries in JACK-PREFIX/lib,
|
|
||||||
for headers in JACK-PREFIX/include],
|
|
||||||
CONFIG_JACK_PREFIX="${withval}", CONFIG_JACK_PREFIX="/usr")
|
|
||||||
|
|
||||||
if test "x${USE_JACK}" = "xyes" ; then
|
|
||||||
AC_MSG_CHECKING( [for jack libraries at ${CONFIG_JACK_PREFIX}] )
|
|
||||||
LA_SEARCH_LIB( JACK_LIB_LOC, JACK_INC_LOC, libjack.la libjack.so libjack.dylib, jack/jack.h,
|
|
||||||
${CONFIG_JACK_PREFIX})
|
|
||||||
|
|
||||||
if test "x${JACK_LIB_LOC}" != "x" ; then
|
|
||||||
|
|
||||||
AC_DEFINE( HAVE_JACK_LIB, 1, [build with JACK audio server support] )
|
|
||||||
if test "x${JACK_INC_LOC}" != "x${SYSTEM_INCLUDE}" ; then
|
|
||||||
JACK_INCFLAGS="-I${JACK_INC_LOC}"
|
|
||||||
fi
|
|
||||||
JACK_LDFLAGS="-L${JACK_LIB_LOC} -ljack"
|
|
||||||
AC_MSG_RESULT( [found at ${CONFIG_JACK_PREFIX}] )
|
|
||||||
else
|
|
||||||
AC_MSG_WARN( [not found, building without JACK support])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT( [building without JACK support] )
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
dnl check for MSG_NOSIGNAL for the send() function in libsocket
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
AC_MSG_CHECKING(for MSG_NOSIGNAL)
|
|
||||||
AC_TRY_COMPILE([#include <sys/socket.h>], [
|
|
||||||
int f = MSG_NOSIGNAL;
|
|
||||||
], [
|
|
||||||
# Yes, we have it...
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_MSG_NOSIGNAL, 1, [use MSG_NOSIGNAL for send()])
|
|
||||||
], [
|
|
||||||
# We'll have to use signals
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
dnl check for POSIX real-time scheduling
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
AC_CHECK_FUNCS( sched_getscheduler sched_getparam )
|
|
||||||
|
|
||||||
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
dnl enable compilation with debug flags
|
|
||||||
dnl-----------------------------------------------------------------------------
|
|
||||||
AC_SUBST(DEBUG_CXXFLAGS)
|
|
||||||
|
|
||||||
AC_ARG_WITH(debug,
|
|
||||||
[ --with-debug enable debug mode [no] ],
|
|
||||||
USE_DEBUG=${withval}, USE_DEBUG="no" )
|
|
||||||
|
|
||||||
if test "x${USE_DEBUG}" == "xyes" ; then
|
|
||||||
DEBUG_CXXFLAGS="-g"
|
|
||||||
AC_MSG_RESULT([compiling in debug mode])
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT([not compiling in debug mode])
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
AC_OUTPUT(Makefile src/Makefile man/Makefile)
|
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
# sample DarkIce configuration file, edit for your needs before using
|
|
||||||
# see the darkice.cfg man page for details
|
|
||||||
|
|
||||||
# this section describes general aspects of the live streaming session
|
|
||||||
[general]
|
|
||||||
duration = 60 # duration of encoding, in seconds. 0 means forever
|
|
||||||
bufferSecs = 5 # size of internal slip buffer, in seconds
|
|
||||||
reconnect = yes # reconnect to the server(s) if disconnected
|
|
||||||
|
|
||||||
# this section describes the audio input that will be streamed
|
|
||||||
[input]
|
|
||||||
device = /dev/dsp # OSS DSP soundcard device for the audio input
|
|
||||||
sampleRate = 22050 # sample rate in Hz. try 11025, 22050 or 44100
|
|
||||||
bitsPerSample = 16 # bits per sample. try 16
|
|
||||||
channel = 2 # channels. 1 = mono, 2 = stereo
|
|
||||||
|
|
||||||
# this section describes a streaming connection to an IceCast server
|
|
||||||
# there may be up to 8 of these sections, named [icecast-0] ... [icecast-7]
|
|
||||||
# these can be mixed with [icecast2-x] and [shoutcast-x] sections
|
|
||||||
[icecast-0]
|
|
||||||
bitrateMode = cbr # constant bit rate
|
|
||||||
bitrate = 96 # bitrate of the mp3 stream sent to the server
|
|
||||||
quality = 0.8 # encoding quality
|
|
||||||
server = yp.yourserver.com
|
|
||||||
# host name of the server
|
|
||||||
port = 8000 # port of the IceCast server, usually 8000
|
|
||||||
password = hackme # source password to the IceCast server
|
|
||||||
mountPoint = sample96 # mount point of this stream on the IceCast server
|
|
||||||
name = DarkIce trial
|
|
||||||
# name of the stream
|
|
||||||
description = This is only a trial
|
|
||||||
# description of the stream
|
|
||||||
url = http://www.yourserver.com
|
|
||||||
# URL related to the stream
|
|
||||||
genre = my own # genre of the stream
|
|
||||||
public = yes # advertise this stream?
|
|
||||||
|
|
||||||
# this section describes a streaming connection to an IceCast2 server
|
|
||||||
# there may be up to 8 of these sections, named [icecast2-0] ... [icecast2-7]
|
|
||||||
# these can be mixed with [icecast-x] and [shoutcast-x] sections
|
|
||||||
[icecast2-0]
|
|
||||||
bitrateMode = abr # average bit rate
|
|
||||||
format = vorbis # format of the stream: ogg vorbis
|
|
||||||
bitrate = 96 # bitrate of the stream sent to the server
|
|
||||||
server = yp.yourserver.com
|
|
||||||
# host name of the server
|
|
||||||
port = 8000 # port of the IceCast2 server, usually 8000
|
|
||||||
password = hackme # source password to the IceCast2 server
|
|
||||||
mountPoint = sample96 # mount point of this stream on the IceCast2 server
|
|
||||||
name = DarkIce trial
|
|
||||||
# name of the stream
|
|
||||||
description = This is only a trial
|
|
||||||
# description of the stream
|
|
||||||
url = http://www.yourserver.com
|
|
||||||
# URL related to the stream
|
|
||||||
genre = my own # genre of the stream
|
|
||||||
public = yes # advertise this stream?
|
|
||||||
|
|
||||||
# this section describes a streaming connection to a ShoutCast server
|
|
||||||
# there may be up to 8 of these sections, named [shoutcast-0] ... [shoutcast-7]
|
|
||||||
# these can be mixed with [icecast-x] and [icecast2-x] sections
|
|
||||||
[shoutcast-0]
|
|
||||||
bitrateMode = vbr # variable bit rate mode
|
|
||||||
quality = 0.5 # encoding quality
|
|
||||||
server = yp.yourserver.com
|
|
||||||
# host name of the server
|
|
||||||
port = 8001 # source port of the ShoutCast server, usually 8001
|
|
||||||
password = hackme # source password to the ShoutCast server
|
|
||||||
name = DarkIce trial
|
|
||||||
# name of the stream
|
|
||||||
url = http://www.yourserver.com
|
|
||||||
# URL related to the stream
|
|
||||||
genre = my own # genre of the stream
|
|
||||||
public = yes # advertise this stream?
|
|
||||||
irc = irc.yourserver.com
|
|
||||||
# IRC info related to the stream
|
|
||||||
aim = aim here # AIM info related to the stream
|
|
||||||
icq = I see you too
|
|
||||||
# ICQ info related to the stream
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,42 +0,0 @@
|
||||||
IUSE="encode oggvorbis alsa jack"
|
|
||||||
|
|
||||||
DESCRIPTION="IceCast live streamer delivering Ogg and mp3 streams simultaneously to multiple hosts."
|
|
||||||
HOMEPAGE="http://darkice.sourceforge.net/"
|
|
||||||
SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz"
|
|
||||||
RESTRICT="nomirror"
|
|
||||||
|
|
||||||
SLOT="0"
|
|
||||||
LICENSE="GPL-2"
|
|
||||||
KEYWORDS="~x86 ~ppc ~sparc ~alpha ~hppa ~amd64"
|
|
||||||
|
|
||||||
DEPEND="encode? ( >=media-sound/lame-3.89 )
|
|
||||||
oggvorbis? ( >=media-libs/libvorbis-1.0 )
|
|
||||||
alsa? ( >=media-libs/alsa-lib-1.0.0 )
|
|
||||||
jack? ( media-sound/jack-audio-connection-kit )"
|
|
||||||
|
|
||||||
src_compile() {
|
|
||||||
if ! use encode && ! use oggvorbis
|
|
||||||
then
|
|
||||||
|
|
||||||
eerror "You need support for mp3 or Ogg Vorbis enconding for this"
|
|
||||||
eerror "package. Please merge again with at least one of the "
|
|
||||||
eerror "\`encode' and \`oggvorbis' USE flags enabled:"
|
|
||||||
eerror
|
|
||||||
eerror " # USE=\"encode\" emerge darkice"
|
|
||||||
eerror " # USE=\"oggvorbis\" emerge darkice"
|
|
||||||
die "Won't build without support for lame nor vorbis"
|
|
||||||
fi
|
|
||||||
|
|
||||||
econf `use_with alsa` \
|
|
||||||
`use_with encode lame` \
|
|
||||||
`use_with oggvorbis vorbis` \
|
|
||||||
`use_with jack` || die
|
|
||||||
|
|
||||||
emake || die "Compilation failed"
|
|
||||||
}
|
|
||||||
|
|
||||||
src_install() {
|
|
||||||
einstall darkicedocdir=${D}/usr/share/doc/${PF} || die
|
|
||||||
|
|
||||||
dodoc AUTHORS ChangeLog COPYING NEWS README TODO
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
IUSE="encode oggvorbis aac alsa jack"
|
|
||||||
|
|
||||||
DESCRIPTION="IceCast live streamer delivering Ogg, mp3 or aac streams simultaneously to multiple hosts."
|
|
||||||
HOMEPAGE="http://darkice.sourceforge.net/"
|
|
||||||
SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz"
|
|
||||||
RESTRICT="nomirror"
|
|
||||||
|
|
||||||
SLOT="0"
|
|
||||||
LICENSE="GPL-2"
|
|
||||||
KEYWORDS="~x86 ~ppc ~sparc ~alpha ~hppa ~amd64"
|
|
||||||
|
|
||||||
DEPEND="encode? ( >=media-sound/lame-3.89 )
|
|
||||||
oggvorbis? ( >=media-libs/libvorbis-1.0 )
|
|
||||||
aac? ( >=media-libs/faac-1.24 )
|
|
||||||
alsa? ( >=media-libs/alsa-lib-1.0.0 )
|
|
||||||
jack? ( media-sound/jack-audio-connection-kit )"
|
|
||||||
|
|
||||||
src_compile() {
|
|
||||||
if ! use encode && ! use oggvorbis && ! use aac
|
|
||||||
then
|
|
||||||
|
|
||||||
eerror "You need support for mp3, Ogg Vorbis or FAAC enconding for this"
|
|
||||||
eerror "package. Please merge again with at least one of the "
|
|
||||||
eerror "\`encode', \`oggvorbis' or \'aac' USE flags enabled:"
|
|
||||||
eerror
|
|
||||||
eerror " # USE=\"encode\" emerge darkice"
|
|
||||||
eerror " # USE=\"oggvorbis\" emerge darkice"
|
|
||||||
eerror " # USE=\"aac\" emerge darkice"
|
|
||||||
die "Won't build without support for lame, vorbis or aac"
|
|
||||||
fi
|
|
||||||
|
|
||||||
econf `use_with alsa` \
|
|
||||||
`use_with encode lame` \
|
|
||||||
`use_with oggvorbis vorbis` \
|
|
||||||
`use_with aac faac` \
|
|
||||||
`use_with jack` || die
|
|
||||||
|
|
||||||
emake || die "Compilation failed"
|
|
||||||
}
|
|
||||||
|
|
||||||
src_install() {
|
|
||||||
einstall darkicedocdir=${D}/usr/share/doc/${PF} || die
|
|
||||||
|
|
||||||
dodoc AUTHORS ChangeLog COPYING NEWS README TODO
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
# Copyright 1999-2006 Gentoo Foundation
|
|
||||||
# Distributed under the terms of the GNU General Public License v2
|
|
||||||
# $Header$
|
|
||||||
|
|
||||||
DESCRIPTION="IceCast live streamer, delivering ogg and mp3 streams simultaneously to multiple hosts."
|
|
||||||
HOMEPAGE="http://darkice.sourceforge.net/"
|
|
||||||
SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz"
|
|
||||||
|
|
||||||
LICENSE="GPL-2"
|
|
||||||
SLOT="0"
|
|
||||||
KEYWORDS="~alpha ~amd64 ~hppa ~ppc ~sparc ~x86"
|
|
||||||
IUSE="alsa encode jack vorbis"
|
|
||||||
|
|
||||||
DEPEND="encode? ( >=media-sound/lame-1.89 )
|
|
||||||
vorbis? ( >=media-libs/libvorbis-1.0 )
|
|
||||||
alsa? ( >=media-libs/alsa-lib-1.0.0 )
|
|
||||||
jack? ( media-sound/jack-audio-connection-kit )"
|
|
||||||
|
|
||||||
src_compile() {
|
|
||||||
if ! use encode && ! use vorbis
|
|
||||||
then
|
|
||||||
|
|
||||||
eerror "You need support for mp3 or Ogg Vorbis enconding for this"
|
|
||||||
eerror "package. Please merge again with at least one of the "
|
|
||||||
eerror "\`encode' and \`vorbis' USE flags enabled:"
|
|
||||||
eerror
|
|
||||||
eerror " # USE=\"encode\" emerge darkice"
|
|
||||||
eerror " # USE=\"vorbis\" emerge darkice"
|
|
||||||
die "Won't build without support for lame nor vorbis"
|
|
||||||
fi
|
|
||||||
|
|
||||||
econf $(use_with alsa) \
|
|
||||||
$(use_with encode lame) \
|
|
||||||
$(use_with jack) \
|
|
||||||
$(use_with vorbis) || die "configuration failed"
|
|
||||||
emake || die "Compilation failed"
|
|
||||||
}
|
|
||||||
|
|
||||||
src_install() {
|
|
||||||
einstall darkicedocdir=${D}/usr/share/doc/${PF} || die "make install failed"
|
|
||||||
|
|
||||||
dodoc AUTHORS ChangeLog NEWS README TODO
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
IUSE="encode mp2 oggvorbis aac alsa jack"
|
|
||||||
|
|
||||||
DESCRIPTION="IceCast live streamer delivering Ogg, mp3, mp2 or aac streams simultaneously to multiple hosts."
|
|
||||||
HOMEPAGE="http://darkice.sourceforge.net/"
|
|
||||||
SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz"
|
|
||||||
RESTRICT="nomirror"
|
|
||||||
|
|
||||||
SLOT="0"
|
|
||||||
LICENSE="GPL-2"
|
|
||||||
KEYWORDS="~x86 ~ppc ~sparc ~alpha ~hppa ~amd64"
|
|
||||||
|
|
||||||
DEPEND="encode? ( >=media-sound/lame-3.89 )
|
|
||||||
mp2? ( >=media-sound/twolame-0.3.6 )
|
|
||||||
oggvorbis? ( >=media-libs/libvorbis-1.0 )
|
|
||||||
aac? ( >=media-libs/faac-1.24 )
|
|
||||||
alsa? ( >=media-libs/alsa-lib-1.0.0 )
|
|
||||||
jack? ( media-sound/jack-audio-connection-kit )"
|
|
||||||
|
|
||||||
src_compile() {
|
|
||||||
if ! use encode && ! use mp2 && ! use oggvorbis && ! use aac
|
|
||||||
then
|
|
||||||
|
|
||||||
eerror "You need support for mp3, Ogg Vorbis or FAAC enconding for this"
|
|
||||||
eerror "package. Please merge again with at least one of the "
|
|
||||||
eerror "\`encode', \'mp2', \`oggvorbis' or \'aac' USE flags enabled:"
|
|
||||||
eerror
|
|
||||||
eerror " # USE=\"encode\" emerge darkice"
|
|
||||||
eerror " # USE=\"mp2\" emerge darkice"
|
|
||||||
eerror " # USE=\"oggvorbis\" emerge darkice"
|
|
||||||
eerror " # USE=\"aac\" emerge darkice"
|
|
||||||
die "Won't build without support for lame, mp2, vorbis or aac"
|
|
||||||
fi
|
|
||||||
|
|
||||||
econf `use_with alsa` \
|
|
||||||
`use_with encode lame` \
|
|
||||||
`use_with mp2 twolame` \
|
|
||||||
`use_with oggvorbis vorbis` \
|
|
||||||
`use_with aac faac` \
|
|
||||||
`use_with jack` || die
|
|
||||||
|
|
||||||
emake || die "Compilation failed"
|
|
||||||
}
|
|
||||||
|
|
||||||
src_install() {
|
|
||||||
einstall darkicedocdir=${D}/usr/share/doc/${PF} || die
|
|
||||||
|
|
||||||
dodoc AUTHORS ChangeLog COPYING NEWS README TODO
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
# Copyright 1999-2006 Gentoo Foundation
|
|
||||||
# Distributed under the terms of the GNU General Public License v2
|
|
||||||
# $Header$
|
|
||||||
|
|
||||||
DESCRIPTION="IceCast live streamer, delivering ogg and mp3 streams simultaneously to multiple hosts."
|
|
||||||
HOMEPAGE="http://darkice.tyrell.hu/"
|
|
||||||
SRC_URI="http://darkice.tyrell.hu/dist/${PV}/${P}.tar.gz"
|
|
||||||
|
|
||||||
LICENSE="GPL-2"
|
|
||||||
SLOT="0"
|
|
||||||
KEYWORDS="~alpha ~amd64 ~hppa ~ppc ~sparc ~x86"
|
|
||||||
IUSE="alsa encode jack vorbis"
|
|
||||||
|
|
||||||
DEPEND="encode? ( >=media-sound/lame-1.89 )
|
|
||||||
vorbis? ( >=media-libs/libvorbis-1.0 )
|
|
||||||
alsa? ( >=media-libs/alsa-lib-1.0.0 )
|
|
||||||
jack? ( media-sound/jack-audio-connection-kit )"
|
|
||||||
|
|
||||||
src_compile() {
|
|
||||||
if ! use encode && ! use vorbis
|
|
||||||
then
|
|
||||||
|
|
||||||
eerror "You need support for mp3 or Ogg Vorbis enconding for this"
|
|
||||||
eerror "package. Please merge again with at least one of the "
|
|
||||||
eerror "\`encode' and \`vorbis' USE flags enabled:"
|
|
||||||
eerror
|
|
||||||
eerror " # USE=\"encode\" emerge darkice"
|
|
||||||
eerror " # USE=\"vorbis\" emerge darkice"
|
|
||||||
die "Won't build without support for lame nor vorbis"
|
|
||||||
fi
|
|
||||||
|
|
||||||
econf $(use_with alsa) \
|
|
||||||
$(use_with encode lame) \
|
|
||||||
$(use_with jack) \
|
|
||||||
$(use_with vorbis) || die "configuration failed"
|
|
||||||
emake || die "Compilation failed"
|
|
||||||
}
|
|
||||||
|
|
||||||
src_install() {
|
|
||||||
einstall darkicedocdir=${D}/usr/share/doc/${PF} || die "make install failed"
|
|
||||||
|
|
||||||
dodoc AUTHORS ChangeLog NEWS README TODO
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
# Copyright 1999-2006 Gentoo Foundation
|
|
||||||
# Distributed under the terms of the GNU General Public License v2
|
|
||||||
# $Header$
|
|
||||||
|
|
||||||
DESCRIPTION="IceCast live streamer, delivering ogg and mp3 streams simultaneously to multiple hosts."
|
|
||||||
HOMEPAGE="http://darkice.tyrell.hu/"
|
|
||||||
SRC_URI="http://darkice.tyrell.hu/dist/${PV}/${P}.tar.gz"
|
|
||||||
|
|
||||||
LICENSE="GPL-2"
|
|
||||||
SLOT="0"
|
|
||||||
KEYWORDS="~alpha ~amd64 ~hppa ~ppc ~sparc ~x86"
|
|
||||||
IUSE="alsa encode jack vorbis"
|
|
||||||
|
|
||||||
DEPEND="encode? ( >=media-sound/lame-1.89 )
|
|
||||||
vorbis? ( >=media-libs/libvorbis-1.0 )
|
|
||||||
alsa? ( >=media-libs/alsa-lib-1.0.0 )
|
|
||||||
jack? ( media-sound/jack-audio-connection-kit )"
|
|
||||||
|
|
||||||
src_compile() {
|
|
||||||
if ! use encode && ! use vorbis
|
|
||||||
then
|
|
||||||
|
|
||||||
eerror "You need support for mp3 or Ogg Vorbis enconding for this"
|
|
||||||
eerror "package. Please merge again with at least one of the "
|
|
||||||
eerror "\`encode' and \`vorbis' USE flags enabled:"
|
|
||||||
eerror
|
|
||||||
eerror " # USE=\"encode\" emerge darkice"
|
|
||||||
eerror " # USE=\"vorbis\" emerge darkice"
|
|
||||||
die "Won't build without support for lame nor vorbis"
|
|
||||||
fi
|
|
||||||
|
|
||||||
econf $(use_with alsa) \
|
|
||||||
$(use_with encode lame) \
|
|
||||||
$(use_with jack) \
|
|
||||||
$(use_with vorbis) || die "configuration failed"
|
|
||||||
emake || die "Compilation failed"
|
|
||||||
}
|
|
||||||
|
|
||||||
src_install() {
|
|
||||||
einstall darkicedocdir=${D}/usr/share/doc/${PF} || die "make install failed"
|
|
||||||
|
|
||||||
dodoc AUTHORS ChangeLog NEWS README TODO
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
# Copyright 1999-2006 Gentoo Foundation
|
|
||||||
# Distributed under the terms of the GNU General Public License v2
|
|
||||||
# $Header$
|
|
||||||
|
|
||||||
DESCRIPTION="IceCast live streamer, delivering ogg and mp3 streams simultaneously to multiple hosts."
|
|
||||||
HOMEPAGE="http://darkice.tyrell.hu/"
|
|
||||||
SRC_URI="http://darkice.tyrell.hu/dist/${PV}/${P}.tar.gz"
|
|
||||||
|
|
||||||
LICENSE="GPL-2"
|
|
||||||
SLOT="0"
|
|
||||||
KEYWORDS="~alpha ~amd64 ~hppa ~ppc ~sparc ~x86"
|
|
||||||
IUSE="alsa encode jack vorbis"
|
|
||||||
|
|
||||||
DEPEND="encode? ( >=media-sound/lame-1.89 )
|
|
||||||
vorbis? ( >=media-libs/libvorbis-1.0 )
|
|
||||||
alsa? ( >=media-libs/alsa-lib-1.0.0 )
|
|
||||||
jack? ( media-sound/jack-audio-connection-kit )"
|
|
||||||
|
|
||||||
src_compile() {
|
|
||||||
if ! use encode && ! use vorbis
|
|
||||||
then
|
|
||||||
|
|
||||||
eerror "You need support for mp3 or Ogg Vorbis enconding for this"
|
|
||||||
eerror "package. Please merge again with at least one of the "
|
|
||||||
eerror "\`encode' and \`vorbis' USE flags enabled:"
|
|
||||||
eerror
|
|
||||||
eerror " # USE=\"encode\" emerge darkice"
|
|
||||||
eerror " # USE=\"vorbis\" emerge darkice"
|
|
||||||
die "Won't build without support for lame nor vorbis"
|
|
||||||
fi
|
|
||||||
|
|
||||||
econf $(use_with alsa) \
|
|
||||||
$(use_with encode lame) \
|
|
||||||
$(use_with jack) \
|
|
||||||
$(use_with vorbis) || die "configuration failed"
|
|
||||||
emake || die "Compilation failed"
|
|
||||||
}
|
|
||||||
|
|
||||||
src_install() {
|
|
||||||
einstall darkicedocdir=${D}/usr/share/doc/${PF} || die "make install failed"
|
|
||||||
|
|
||||||
dodoc AUTHORS ChangeLog NEWS README TODO
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
# Copyright 1999-2006 Gentoo Foundation
|
|
||||||
# Distributed under the terms of the GNU General Public License v2
|
|
||||||
# $Header$
|
|
||||||
|
|
||||||
IUSE=""
|
|
||||||
DESCRIPTION="TwoLAME is an optimised MPEG Audio Layer 2 (MP2) encoder"
|
|
||||||
HOMEPAGE="http://www.twolame.org/"
|
|
||||||
SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz"
|
|
||||||
RESTRICT="nomirror"
|
|
||||||
|
|
||||||
SLOT="0"
|
|
||||||
LICENSE="GPL-2"
|
|
||||||
KEYWORDS="~x86 ~ppc ~sparc ~alpha ~hppa ~amd64"
|
|
||||||
|
|
||||||
DEPEND=">=media-libs/libsndfile-1.0.11"
|
|
||||||
|
|
||||||
src_install() {
|
|
||||||
make DESTDIR=${D} || die
|
|
||||||
|
|
||||||
dodoc AUTHORS ChangeLog COPYING README TODO
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
%{!?dist: %define dist fc3}
|
|
||||||
|
|
||||||
Summary : DarkIce live IceCast / ShoutCast streamer
|
|
||||||
Name: darkice
|
|
||||||
Vendor: Tyrell Hungary
|
|
||||||
Packager: Akos Maroy <darkeye@tyrell.hu>
|
|
||||||
Version: 0.18
|
|
||||||
Release: 1.%{dist}
|
|
||||||
Copyright: GPL
|
|
||||||
Group: Applications/Multimedia
|
|
||||||
Source: http://prdownloads.sourceforge.net/darkice/darkice-%{version}.tar.gz
|
|
||||||
URL: http://darkice.sourceforge.net/
|
|
||||||
Provides: darkice
|
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
|
||||||
BuildPrereq: lame-devel libogg-devel libvorbis-devel
|
|
||||||
%if %{dist} != el3
|
|
||||||
BuildPrereq: jack-audio-connection-kit-devel
|
|
||||||
%endif
|
|
||||||
Prefix: /usr
|
|
||||||
|
|
||||||
%description
|
|
||||||
DarkIce is an IceCast, IceCast2 and ShoutCast live audio streamer. It
|
|
||||||
takes audio input from a sound card, encodes it into mp3 and/or Ogg Vorbis,
|
|
||||||
and sends the mp3 stream to one or more IceCast and/or ShoutCast servers,
|
|
||||||
the Ogg Vorbis stream to one or more IceCast2 servers.
|
|
||||||
|
|
||||||
%prep
|
|
||||||
%setup
|
|
||||||
|
|
||||||
%build
|
|
||||||
%configure \
|
|
||||||
%if %{dist} == el3
|
|
||||||
--without-alsa --without-jack
|
|
||||||
%endif
|
|
||||||
|
|
||||||
make all
|
|
||||||
|
|
||||||
%install
|
|
||||||
rm -fr %{buildroot}
|
|
||||||
%makeinstall
|
|
||||||
|
|
||||||
%clean
|
|
||||||
rm -rf %{buildroot}
|
|
||||||
|
|
||||||
%files
|
|
||||||
%defattr (-, root, root)
|
|
||||||
%doc COPYING ChangeLog README TODO AUTHORS
|
|
||||||
%config(noreplace) %{_sysconfdir}/darkice.cfg
|
|
||||||
%{_bindir}/darkice
|
|
||||||
%{_mandir}/man1/darkice.1*
|
|
||||||
%{_mandir}/man5/darkice.cfg.5*
|
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
|
||||||
* Thu May 18 2006 Akos Maroy <darkeye@tyrell.hu> 0.18-1
|
|
||||||
- rewrite the spec file for 0.18
|
|
||||||
* Tue Apr 19 2005 Akos Maroy <darkeye@tyrell.hu> 0.16-1
|
|
||||||
- rewrite the spec file for 0.16
|
|
||||||
* Tue Apr 19 2005 Akos Maroy <darkeye@tyrell.hu> 0.15-1
|
|
||||||
- rewrite the spec file for 0.15
|
|
|
@ -1,151 +0,0 @@
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
# 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 <cefiar1@optushome.com.au>
|
|
||||||
#
|
|
||||||
# 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 <darkeye@tyrell.hu>
|
|
||||||
URL: http://www.mp3dev.org/mp3/
|
|
||||||
Group: Applications/Multimedia
|
|
||||||
Source: http://prdownloads.sourceforge.net/darkice/%{name}-%{ver}.tar.gz
|
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{ver}-root
|
|
||||||
Prefix: %{prefix}
|
|
||||||
Provides: lame
|
|
||||||
|
|
||||||
%description
|
|
||||||
LAME is an educational tool to be used for learning about MP3 encoding. The
|
|
||||||
goal of the LAME project is to use the open source model to improve the
|
|
||||||
psycho acoustics, noise shaping and speed of MP3. Another goal of the LAME
|
|
||||||
project is to use these improvements for the basis of a patent free audio
|
|
||||||
compression codec for the GNU project.
|
|
||||||
|
|
||||||
This build is optimized for %{_target}.
|
|
||||||
|
|
||||||
# ============================================================ devel sub-package
|
|
||||||
%package devel
|
|
||||||
Summary: Shared and static libraries for LAME.
|
|
||||||
Group: Development/Libraries
|
|
||||||
Requires: %{name} = %{version}
|
|
||||||
|
|
||||||
%description devel
|
|
||||||
LAME is an educational tool to be used for learning about MP3 encoding.
|
|
||||||
This package contains both the shared and the static libraries from the
|
|
||||||
LAME project.
|
|
||||||
|
|
||||||
You will also need to install the main lame package in order to install
|
|
||||||
these libraries.
|
|
||||||
|
|
||||||
This build is optimized for %{_target}.
|
|
||||||
|
|
||||||
# =================================================================== prep stage
|
|
||||||
%prep
|
|
||||||
%setup -n %{name}-%{ver}
|
|
||||||
|
|
||||||
|
|
||||||
# ================================================================== build stage
|
|
||||||
%build
|
|
||||||
export CC=gcc3
|
|
||||||
export CFLAGS="-O9"
|
|
||||||
%configure --with-fileio=lame \
|
|
||||||
--without-vorbis \
|
|
||||||
--disable-gtktest \
|
|
||||||
--enable-nasm \
|
|
||||||
--enable-expopt=full
|
|
||||||
make
|
|
||||||
|
|
||||||
|
|
||||||
# ================================================================ install stage
|
|
||||||
%install
|
|
||||||
%makeinstall
|
|
||||||
|
|
||||||
|
|
||||||
# ======================================================================== clean
|
|
||||||
%clean
|
|
||||||
rm -rf $RPM_BUILD_ROOT
|
|
||||||
make clean
|
|
||||||
|
|
||||||
|
|
||||||
# =========================================================== main package files
|
|
||||||
%files
|
|
||||||
%defattr (-,root,root)
|
|
||||||
%doc LICENSE USAGE COPYING TODO README*
|
|
||||||
%doc doc/html
|
|
||||||
%{_bindir}/lame
|
|
||||||
%{_mandir}/man1/lame.1*
|
|
||||||
%{_libdir}/libmp3lame.so.*
|
|
||||||
|
|
||||||
|
|
||||||
# ====================================================== devel sub-package files
|
|
||||||
%files devel
|
|
||||||
%defattr (-,root,root)
|
|
||||||
%doc API HACKING STYLEGUIDE
|
|
||||||
%{_includedir}/lame/lame.h
|
|
||||||
%{_libdir}/libmp3lame.la
|
|
||||||
%{_libdir}/libmp3lame.a
|
|
||||||
%{_libdir}/libmp3lame.so
|
|
||||||
|
|
||||||
|
|
||||||
# =================================================================== change log
|
|
||||||
#
|
|
||||||
# $Log$
|
|
||||||
# Revision 1.1 2005/04/14 11:58:08 darkeye
|
|
||||||
# moved directory rpm to etc/rpm
|
|
||||||
#
|
|
||||||
# Revision 1.4 2002/02/19 14:52:41 darkeye
|
|
||||||
# updated for lame 3.91
|
|
||||||
#
|
|
||||||
# Revision 1.3 2001/09/13 05:06:41 darkeye
|
|
||||||
# removed references to SourceForget FTP sites, as they are phased out
|
|
||||||
#
|
|
||||||
# Revision 1.2 2001/09/09 09:06:26 darkeye
|
|
||||||
# lame RPM is now created with gcc3 and full optimizations
|
|
||||||
#
|
|
||||||
# Revision 1.1 2001/09/02 12:46:05 darkeye
|
|
||||||
# added RPM package creation scripts
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
|
@ -1,251 +0,0 @@
|
||||||
#!/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
|
|
|
@ -1,4 +0,0 @@
|
||||||
man_MANS = darkice.1 darkice.cfg.5
|
|
||||||
|
|
||||||
EXTRA_DIST = ${man_MANS}
|
|
||||||
|
|
|
@ -1,154 +0,0 @@
|
||||||
.TH darkice 1 "November 20, 2007" "DarkIce" "DarkIce live audio streamer"
|
|
||||||
.SH NAME
|
|
||||||
darkice \- an icecast / shoutcast live audio streamer
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.B darkice
|
|
||||||
[options] -c config.file
|
|
||||||
.SH DESCRIPTION
|
|
||||||
.PP
|
|
||||||
DarkIce as a live audio streamer. It records audio from an audio interface (e.g. sound card), encodes it and sends it to a streaming server.
|
|
||||||
DarkIce can record from:
|
|
||||||
|
|
||||||
* OSS audio devices
|
|
||||||
* ALSA audio devices
|
|
||||||
* Solaris audio interface
|
|
||||||
* Jack sources
|
|
||||||
|
|
||||||
DarkIce can encode in the following formats:
|
|
||||||
|
|
||||||
* mp3 - using the lame library
|
|
||||||
* mp2 - using the twolame library
|
|
||||||
* Ogg Vorbis
|
|
||||||
* AAC - using the faac library
|
|
||||||
* AAC HEv2 - using the libaacplus (3GPP reference code)
|
|
||||||
|
|
||||||
DarkIce can send the encoded stream to the following streaming servers:
|
|
||||||
|
|
||||||
* ShoutCast
|
|
||||||
* IceCast 1.3.x and 2.x
|
|
||||||
* Darwin Streaming Server
|
|
||||||
|
|
||||||
Darkice runs on the following operating systems:
|
|
||||||
|
|
||||||
* FreeBSD
|
|
||||||
* Linux on intel and PowerPC
|
|
||||||
* MacOS X
|
|
||||||
* NetBSD / OpenBSD
|
|
||||||
* SUN Solaris
|
|
||||||
|
|
||||||
.B DarkIce
|
|
||||||
uses
|
|
||||||
.SM POSIX
|
|
||||||
real-time scheduling to keep up with sound card input.
|
|
||||||
.SM POSIX
|
|
||||||
real-time scheduling is only available if the program is run as root.
|
|
||||||
Therefore it is recommended that
|
|
||||||
.B DarkIce
|
|
||||||
is run as root.
|
|
||||||
|
|
||||||
.SH OPTIONS
|
|
||||||
.TP
|
|
||||||
.BI "\-c " config.file
|
|
||||||
Specifies what configuration file to use.
|
|
||||||
If not specified, /etc/darkice.cfg will be used.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.BI "\-v " n
|
|
||||||
Sets the verbosity level, between 0 and 10. 0 is silent, 10 is loud.
|
|
||||||
Defaults to 1.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.BI "\-h "
|
|
||||||
Prints the help page and exits.
|
|
||||||
|
|
||||||
|
|
||||||
.SH BUGS
|
|
||||||
.PP
|
|
||||||
Lots of bugs.
|
|
||||||
|
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
darkice.cfg(5)
|
|
||||||
|
|
||||||
|
|
||||||
.SH AUTHOR
|
|
||||||
Akos Maroy
|
|
||||||
.I <darkeye@tyrell.hu>
|
|
||||||
|
|
||||||
|
|
||||||
.SH ACKNOWLEDGEMENTS
|
|
||||||
Developed with contributions by
|
|
||||||
|
|
||||||
Jim Crilly, <JCrilly@MSA.com>
|
|
||||||
aNa|0Gue, <analogue@glop.org>
|
|
||||||
Robin P. Blanchard, <Robin_Blanchard@gactr.uga.edu>
|
|
||||||
Tom Gray, <tomg@future-i.com>
|
|
||||||
Michael Smith, <msmith@labyrinth.net.au>
|
|
||||||
Julius O. Smith, <jos@ccrma.stanford.edu>
|
|
||||||
the OSALP team, http://osalp.sourceforge.net
|
|
||||||
Kristjan G. Bjarnason <kgb@gangverk.is>
|
|
||||||
Nicu Pavel <npavel@ituner.com>
|
|
||||||
Kai Krakow <kai@kaishome.de>
|
|
||||||
Atsuhiko Yamanaka <ymnk@jcraft.com>
|
|
||||||
Ricardo Galli <gallir@uib.es>
|
|
||||||
John Hay <jhay@icomtek.csir.co.za>
|
|
||||||
Christian Forster <forster@like.e-technik.uni-erlangen.de>
|
|
||||||
John Deeny <taqueso@dilapidated.org>
|
|
||||||
Robert Lunnon <bobl@optushome.com.au>
|
|
||||||
Enrico Ardizzoni <craken@users.sourceforge.net>
|
|
||||||
Deti Fliegl <deti@fliegl.de>
|
|
||||||
Nicholas J. Humfrey <njh@ecs.soton.ac.uk>
|
|
||||||
Joel Ebel <jbebel@ncsu.edu>
|
|
||||||
<jochen2@users.sourceforge.net>
|
|
||||||
Alexander Vlasov <zulu@galaradio.com>
|
|
||||||
Mariusz Mazur <mmazur@kernel.pl>
|
|
||||||
dsk <derrick@csociety.org>
|
|
||||||
Clyde Stubbs <clyde@htsoft.com>
|
|
||||||
Jens Maurer <Jens.Maurer@gmx.net>
|
|
||||||
Elod Horvath <elod@itfais.com>
|
|
||||||
Pierre Souchay <pierre@souchay.net>
|
|
||||||
Daniel Hazelbaker <daniel@highdesertchurch.com>
|
|
||||||
Alessandro Beretta <alessandro.baretta@radiomaria.org>
|
|
||||||
Roland Hermans <roland.hermans@omroepvenray.nl>
|
|
||||||
Rafael Diniz <rafael@riseup.net>
|
|
||||||
|
|
||||||
.SH LINKS
|
|
||||||
Project homepage:
|
|
||||||
.I http://darkice.sf.net/
|
|
||||||
|
|
||||||
.B IceCast
|
|
||||||
homepage:
|
|
||||||
.I http://www.icecast.org/
|
|
||||||
|
|
||||||
.B ShoutCast
|
|
||||||
homepage:
|
|
||||||
.I http://www.shoutcast.com/
|
|
||||||
|
|
||||||
.B Darwin Streaming Server
|
|
||||||
homepage:
|
|
||||||
.I http://developer.apple.com/darwin/projects/streaming/
|
|
||||||
|
|
||||||
.B Lame
|
|
||||||
homepage:
|
|
||||||
.I http://www.mp3dev.org/mp3/
|
|
||||||
|
|
||||||
.B TwoLame
|
|
||||||
homepage:
|
|
||||||
.I http://www.twolame.org/
|
|
||||||
|
|
||||||
.B Ogg Vorbis
|
|
||||||
homepage:
|
|
||||||
.I http://www.xiph.org/ogg/vorbis/
|
|
||||||
|
|
||||||
.B faac
|
|
||||||
homepage:
|
|
||||||
.I http://www.audiocoding.com/
|
|
||||||
|
|
||||||
.B libaacplus
|
|
||||||
homepage:
|
|
||||||
.I http://http://tipok.org.ua/node/17
|
|
||||||
|
|
||||||
.B DarkSnow
|
|
||||||
GTK front-end:
|
|
||||||
.I http://darksnow.radiolivre.org/index.en.html
|
|
||||||
written by Rafael Diniz
|
|
|
@ -1,674 +0,0 @@
|
||||||
.TH darkice.cfg 5 "February 25, 2007" "DarkIce" "DarkIce live audio streamer"
|
|
||||||
.SH NAME
|
|
||||||
darkice.cfg \- configuration file for darkice
|
|
||||||
.SH DESCRIPTION
|
|
||||||
.PP
|
|
||||||
The configuration file consists of sections, with key = value pairs
|
|
||||||
separated with spaces and/or tabs inside each secion:
|
|
||||||
|
|
||||||
.nf
|
|
||||||
[section1]
|
|
||||||
# this is a whole line comment
|
|
||||||
key = value
|
|
||||||
an ugly key name = long value # this end is a comment too
|
|
||||||
|
|
||||||
[section2]
|
|
||||||
# this is a whole line comment in section 2
|
|
||||||
key = value
|
|
||||||
an ugly key name = long value # this end is a comment too
|
|
||||||
.fi
|
|
||||||
|
|
||||||
A proper
|
|
||||||
.B DarkIce
|
|
||||||
configuration file contains the following sections:
|
|
||||||
.nf
|
|
||||||
[general]
|
|
||||||
[input]
|
|
||||||
[icecast-0] ... [icecast-7]
|
|
||||||
[icecast2-0] ... [icecast2-7]
|
|
||||||
[shoutcast-0] ... [shoutcast-7]
|
|
||||||
[file-0] ... [file-7]
|
|
||||||
.fi
|
|
||||||
|
|
||||||
The order of the sections is not important. Sections [general] and [input]
|
|
||||||
are required, and at least one of [icecast-x], [icecast2-x], [shoutcast-x]
|
|
||||||
or [file-x] is needed.
|
|
||||||
|
|
||||||
In particular, the following sections and values are recognized:
|
|
||||||
.PP
|
|
||||||
.B [general]
|
|
||||||
|
|
||||||
This section describes general operational parameters (required).
|
|
||||||
|
|
||||||
Required values:
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.I duration
|
|
||||||
Time for DarkIce to run, in seconds. If 0, run forever.
|
|
||||||
.TP
|
|
||||||
.I bufferSecs
|
|
||||||
Data read from the sound card is buffered before sent to
|
|
||||||
the encoder. Each buffer will be able to hold this
|
|
||||||
many seconds of samples.
|
|
||||||
|
|
||||||
.PP
|
|
||||||
Optional values:
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.I reconnect
|
|
||||||
Try to reconnect to the server(s) if the connection is broken during
|
|
||||||
streaming, "yes" or "no". (optional parameter, defaults to "yes")
|
|
||||||
.TP
|
|
||||||
.I realtime
|
|
||||||
Use POSIX realtime scheduling, "yes" or "no".
|
|
||||||
(optional parameter, defaults to "yes")
|
|
||||||
|
|
||||||
|
|
||||||
.PP
|
|
||||||
.B [input]
|
|
||||||
|
|
||||||
This section describes the input (required).
|
|
||||||
|
|
||||||
Required values:
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.I device
|
|
||||||
Specify the device to record from, which can be an OSS DSP device,
|
|
||||||
an ALSA source or you can use Jack audio.
|
|
||||||
- OSS DSP audio device to record from (e.g. /dev/dsp)
|
|
||||||
- ALSA DSP device name (e.g. hwplug:0,0)
|
|
||||||
- the string 'jack', to have an unconnected Jack port, or
|
|
||||||
'jack_auto' to automatically make Jack connect to the first source.
|
|
||||||
.TP
|
|
||||||
.I sampleRate
|
|
||||||
The sample rate to record with, samples per second
|
|
||||||
(e.g. 44100 for 44.1kHz CD-quality audio, 22050 for 22kHz or 11025
|
|
||||||
for 11kHz)
|
|
||||||
.TP
|
|
||||||
.I bitsPerSample
|
|
||||||
Number of bits to use for each sample (e.g. 8 bits or 16 bits)
|
|
||||||
.TP
|
|
||||||
.I channel
|
|
||||||
Number of channels to record (e.g. 1 for mono, 2 for stereo)
|
|
||||||
.TP
|
|
||||||
.I jackClientName
|
|
||||||
The name of the jack input channel created by darkice if device=jack
|
|
||||||
is specified.
|
|
||||||
|
|
||||||
.PP
|
|
||||||
.B [icecast-x]
|
|
||||||
|
|
||||||
This section describes an output to an
|
|
||||||
.B IceCast 1.3.x
|
|
||||||
server or
|
|
||||||
.B Darwin Streaming Server
|
|
||||||
, while encoding
|
|
||||||
with a lame encoder. There may be at most 8 outputs, numbered from 0 ... 7.
|
|
||||||
The number is included in the section name (e.g. [icecast-0] ... [icecast-7]).
|
|
||||||
The stream will be reachable at
|
|
||||||
.I http://<server>:<port>/<mountPoint>
|
|
||||||
|
|
||||||
Required values:
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.I bitrateMode
|
|
||||||
The bit rate mode of the encoding, either "cbr", "abr" or "vbr",
|
|
||||||
standing for constant bit rate, average bit rate and variable bit
|
|
||||||
respectively. Use the bitrate and/or quality values to specify details
|
|
||||||
of the appropriate bit rate mode.
|
|
||||||
.TP
|
|
||||||
.I bitrate
|
|
||||||
Bit rate to encode to in kBits / sec (e.g. 96). Only used when cbr or
|
|
||||||
abr bit rate modes are specified.
|
|
||||||
.TP
|
|
||||||
.I quality
|
|
||||||
The quality of encoding a value between 0.0 .. 1.0 (e.g. 0.8), with 1.0 being
|
|
||||||
the highest quality. Use a value greater than 0.0. Only used when cbr or vbr
|
|
||||||
bit rate modes are specified.
|
|
||||||
.TP
|
|
||||||
.I server
|
|
||||||
The
|
|
||||||
.B IceCast
|
|
||||||
server's name (e.g. yp.yourserver.com)
|
|
||||||
.TP
|
|
||||||
.I port
|
|
||||||
The port to connect to the IceCast server (e.g. 8000)
|
|
||||||
.TP
|
|
||||||
.I password
|
|
||||||
The password to use to connect to the
|
|
||||||
.B IceCast
|
|
||||||
server
|
|
||||||
.TP
|
|
||||||
.I mountPoint
|
|
||||||
Mount point for the stream on the server
|
|
||||||
|
|
||||||
.PP
|
|
||||||
Optional values:
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.I sampleRate
|
|
||||||
The sample rate of the encoded mp3 output. If not specified, defaults
|
|
||||||
to the value of the input sample rate.
|
|
||||||
.TP
|
|
||||||
.I channel
|
|
||||||
Number of channels for the mp3 output (e.g. 1 for mono, 2 for stereo).
|
|
||||||
If not specified, defaults to the value of the input sample rate.
|
|
||||||
.TP
|
|
||||||
.I name
|
|
||||||
Name of the stream
|
|
||||||
.TP
|
|
||||||
.I description
|
|
||||||
Description of the stream
|
|
||||||
.TP
|
|
||||||
.I url
|
|
||||||
Url related to the stream
|
|
||||||
.TP
|
|
||||||
.I genre
|
|
||||||
Genre of the stream
|
|
||||||
.TP
|
|
||||||
.I public
|
|
||||||
"yes" or "no", wether the stream is public
|
|
||||||
.TP
|
|
||||||
.I remoteDumpFile
|
|
||||||
The file the
|
|
||||||
.B IceCast
|
|
||||||
server should dump the contents of
|
|
||||||
this stream on its side.
|
|
||||||
.TP
|
|
||||||
.I localDumpFile
|
|
||||||
Dump the same mp3 data sent to the
|
|
||||||
.B IceCast
|
|
||||||
server to this local file.
|
|
||||||
.TP
|
|
||||||
.I fileAddDate
|
|
||||||
"yes" or "no" if you want to automaticaly insert a date string in
|
|
||||||
the localDumpFile name before its extension or at the end of file name if
|
|
||||||
no extension present
|
|
||||||
.TP
|
|
||||||
.I fileDateFormat
|
|
||||||
The date format to use for appending the date to the dump file name.
|
|
||||||
Defaults to "[%m-%d-%Y-%H-%M-%S]". All format strings acceptable by strftime()
|
|
||||||
can be used, see the strftime man page for details. Only applicable is
|
|
||||||
fileAddDate is "true".
|
|
||||||
.TP
|
|
||||||
.I lowpass
|
|
||||||
Lowpass filter setting for the lame encoder, in Hz. Frequencies above
|
|
||||||
the specified value will be cut.
|
|
||||||
If not set or set to 0, the encoder's default behaviour is used.
|
|
||||||
If set to -1, the filter is disabled.
|
|
||||||
.TP
|
|
||||||
.I highpass
|
|
||||||
Highpass filter setting for the lame encoder, in Hz. Frequencies below
|
|
||||||
the specified value will be cut.
|
|
||||||
If not set or set to 0, the encoder's default behaviour is used.
|
|
||||||
If set to -1, the filter is disabled.
|
|
||||||
|
|
||||||
.PP
|
|
||||||
.B [icecast2-x]
|
|
||||||
|
|
||||||
This section describes an output to an
|
|
||||||
.B IceCast2
|
|
||||||
server, while encoding with the ogg vobis encoder.
|
|
||||||
There may be at most 8 outputs, numbered from 0 ... 7.
|
|
||||||
The number is included in the section name (e.g. [icecast2-0] ... [icecast2-7]).
|
|
||||||
The stream will be reachable at
|
|
||||||
.I http://<server>:<port>/<mountPoint>
|
|
||||||
.P
|
|
||||||
.B DarkIce
|
|
||||||
supports both fixed bitrate and variable bitrate vorbis streams. When
|
|
||||||
using fixed bitrate, specify the bitrate using the
|
|
||||||
.I bitrate
|
|
||||||
field. When using variable bitrate, specify the quality of the stream by the
|
|
||||||
.I quality
|
|
||||||
field, which is a value between 0.0 and 1.0.
|
|
||||||
|
|
||||||
Required values:
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.I format
|
|
||||||
Format of the stream sent to the
|
|
||||||
.B IceCast2
|
|
||||||
server. Supported formats are 'vorbis', 'mp3', 'mp2', 'aac' and 'aacp'.
|
|
||||||
.TP
|
|
||||||
.I bitrateMode
|
|
||||||
The bit rate mode of the encoding, either "cbr", "abr" or "vbr",
|
|
||||||
standing for constant bit rate, average bit rate and variable bit
|
|
||||||
respectively. Use the bitrate and/or quality values to specify details
|
|
||||||
of the appropriate bit rate mode.
|
|
||||||
.TP
|
|
||||||
.I bitrate
|
|
||||||
Bit rate to encode to in kBits / sec (e.g. 96). Only used when cbr or
|
|
||||||
abr bit rate modes are specified.
|
|
||||||
.TP
|
|
||||||
.I quality
|
|
||||||
The quality of encoding a value between 0.0 .. 1.0 (e.g. 0.8), with 1.0 being
|
|
||||||
the highest quality. Use a value greater than 0.0. Only used when vbr
|
|
||||||
bit rate mode is specified for Ogg Vorbis format, or in vbr and abr
|
|
||||||
modes for mp3 and mp2 format.
|
|
||||||
.TP
|
|
||||||
.I server
|
|
||||||
The
|
|
||||||
.B IceCast2
|
|
||||||
server's name (e.g. yp.yourserver.com)
|
|
||||||
.TP
|
|
||||||
.I port
|
|
||||||
The port to connect to the IceCast server (e.g. 8000)
|
|
||||||
.TP
|
|
||||||
.I password
|
|
||||||
The password to use to connect to the
|
|
||||||
.B IceCast2
|
|
||||||
server
|
|
||||||
.TP
|
|
||||||
.I mountPoint
|
|
||||||
Mount point for the stream on the server
|
|
||||||
|
|
||||||
.PP
|
|
||||||
Optional values:
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.I sampleRate
|
|
||||||
The sample rate of the encoded output. If not specified, defaults
|
|
||||||
to the value of the input sample rate.
|
|
||||||
.TP
|
|
||||||
.I channel
|
|
||||||
Number of channels for the output (e.g. 1 for mono, 2 for stereo).
|
|
||||||
If not specified, defaults to the value of the input sample rate.
|
|
||||||
Different channels for input and output are only supported for mp3,
|
|
||||||
but not for Ogg Vorbis.
|
|
||||||
.TP
|
|
||||||
.I maxBitrate
|
|
||||||
The maximum bitrate of the stream. Only used when in cbr mode and in
|
|
||||||
Ogg Vorbis format.
|
|
||||||
.TP
|
|
||||||
.I name
|
|
||||||
Name of the stream
|
|
||||||
.TP
|
|
||||||
.I description
|
|
||||||
Description of the stream
|
|
||||||
.TP
|
|
||||||
.I url
|
|
||||||
Url related to the stream
|
|
||||||
.TP
|
|
||||||
.I genre
|
|
||||||
Genre of the stream
|
|
||||||
.TP
|
|
||||||
.I public
|
|
||||||
"yes" or "no", wether the stream is public
|
|
||||||
.TP
|
|
||||||
.I localDumpFile
|
|
||||||
Dump the same Ogg Vorbis data sent to the
|
|
||||||
.B IceCast2
|
|
||||||
server to this local file.
|
|
||||||
.TP
|
|
||||||
.I fileAddDate
|
|
||||||
"yes" or "no" if you want to automaticaly insert a date string in
|
|
||||||
the localDumpFile name before its extension or at the end of file name if
|
|
||||||
no extension present
|
|
||||||
.TP
|
|
||||||
.I fileDateFormat
|
|
||||||
The date format to use for appending the date to the dump file name.
|
|
||||||
Defaults to "[%m-%d-%Y-%H-%M-%S]". All format strings acceptable by strftime()
|
|
||||||
can be used, see the strftime man page for details. Only applicable is
|
|
||||||
fileAddDate is "true".
|
|
||||||
.TP
|
|
||||||
.I lowpass
|
|
||||||
Lowpass filter setting for the lame encoder, in Hz. Frequencies above
|
|
||||||
the specified value will be cut.
|
|
||||||
If not set or set to 0, the encoder's default behaviour is used.
|
|
||||||
If set to -1, the filter is disabled.
|
|
||||||
Only has effect if the mp3 or mp2 format is used.
|
|
||||||
.TP
|
|
||||||
.I highpass
|
|
||||||
Highpass filter setting for the lame encoder, in Hz. Frequencies below
|
|
||||||
the specified value will be cut.
|
|
||||||
If not set or set to 0, the encoder's default behaviour is used.
|
|
||||||
If set to -1, the filter is disabled.
|
|
||||||
Only has effect if the mp3 or mp2 format is used.
|
|
||||||
|
|
||||||
.PP
|
|
||||||
.B [shoutcast-x]
|
|
||||||
|
|
||||||
This section describes an output to a
|
|
||||||
.B ShoutCast
|
|
||||||
server, while encoding
|
|
||||||
with a lame encoder. There may be at most 8 outputs, numbered from 0 ... 7.
|
|
||||||
The number is included in the section name
|
|
||||||
(e.g. [shoutcast-0] ... [shoutcast-7]).
|
|
||||||
The stream will be reachable at
|
|
||||||
.I http://<server>:<port-1>/
|
|
||||||
|
|
||||||
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 mountPoint
|
|
||||||
Mount point for the stream on the server. Only works on Darwin Streaming
|
|
||||||
Server, the original Shoutcast server does not support mount points
|
|
||||||
.TP
|
|
||||||
.I sampleRate
|
|
||||||
The sample rate of the encoded mp3 output. If not specified, defaults
|
|
||||||
to the value of the input sample rate.
|
|
||||||
.TP
|
|
||||||
.I channel
|
|
||||||
Number of channels for the mp3 output (e.g. 1 for mono, 2 for stereo).
|
|
||||||
If not specified, defaults to the value of the input sample rate.
|
|
||||||
.TP
|
|
||||||
.I name
|
|
||||||
Name of the stream
|
|
||||||
.TP
|
|
||||||
.I url
|
|
||||||
Url related to the stream
|
|
||||||
.TP
|
|
||||||
.I genre
|
|
||||||
Genre of the stream
|
|
||||||
.TP
|
|
||||||
.I public
|
|
||||||
"yes" or "no", wether the stream is public
|
|
||||||
.TP
|
|
||||||
.I irc
|
|
||||||
IRC information related to the stream
|
|
||||||
.TP
|
|
||||||
.I aim
|
|
||||||
AIM information related to the stream
|
|
||||||
.TP
|
|
||||||
.I icq
|
|
||||||
ICQ information related to the stream
|
|
||||||
.TP
|
|
||||||
.I lowpass
|
|
||||||
Lowpass filter setting for the lame encoder, in Hz. Frequencies above
|
|
||||||
the specified value will be cut.
|
|
||||||
If not set or set to 0, the encoder's default behaviour is used.
|
|
||||||
If set to -1, the filter is disabled.
|
|
||||||
.TP
|
|
||||||
.I highpass
|
|
||||||
Highpass filter setting for the lame encoder, in Hz. Frequencies below
|
|
||||||
the specified value will be cut.
|
|
||||||
If not set or set to 0, the encoder's default behaviour is used.
|
|
||||||
If set to -1, the filter is disabled.
|
|
||||||
.TP
|
|
||||||
.I localDumpFile
|
|
||||||
Dump the same mp3 data sent to the
|
|
||||||
.B ShoutCast
|
|
||||||
server to this local file.
|
|
||||||
.TP
|
|
||||||
.I fileAddDate
|
|
||||||
"yes" or "no" if you want to automaticaly insert a date string in
|
|
||||||
the localDumpFile name before its extension or at the end of file name if
|
|
||||||
no extension present
|
|
||||||
.TP
|
|
||||||
.I fileDateFormat
|
|
||||||
The date format to use for appending the date to the dump file name.
|
|
||||||
Defaults to "[%m-%d-%Y-%H-%M-%S]". All format strings acceptable by strftime()
|
|
||||||
can be used, see the strftime man page for details. Only applicable is
|
|
||||||
fileAddDate is "true".
|
|
||||||
.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', 'mp2', 'vorbis', 'aac' or 'aacp'.
|
|
||||||
.TP
|
|
||||||
.I bitrateMode
|
|
||||||
The bit rate mode of the encoding, either "cbr", "abr" or "vbr",
|
|
||||||
standing for constant bit rate, average bit rate and variable bit
|
|
||||||
respectively. Use the bitrate and/or quality values to specify details
|
|
||||||
of the appropriate bit rate mode.
|
|
||||||
.TP
|
|
||||||
.I bitrate
|
|
||||||
Bit rate to encode to in kBits / sec (e.g. 96). Only used when cbr or
|
|
||||||
abr bit rate modes are specified.
|
|
||||||
.TP
|
|
||||||
.I quality
|
|
||||||
The quality of encoding a value between 0.0 .. 1.0 (e.g. 0.8), with 1.0 being
|
|
||||||
the highest quality. Use a value greater than 0.0. Only used when cbr or vbr
|
|
||||||
bit rate modes are specified.
|
|
||||||
.TP
|
|
||||||
.I fileName
|
|
||||||
The name of the local file to save the encoded data into.
|
|
||||||
|
|
||||||
.PP
|
|
||||||
Optional values:
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.I sampleRate
|
|
||||||
The sample rate of the encoded mp3 output. If not specified, defaults
|
|
||||||
to the value of the input sample rate.
|
|
||||||
Only used if the output format is mp3.
|
|
||||||
.TP
|
|
||||||
.I lowpass
|
|
||||||
Lowpass filter setting for the lame encoder, in Hz. Frequencies above
|
|
||||||
the specified value will be cut.
|
|
||||||
If not set or set to 0, the encoder's default behaviour is used.
|
|
||||||
If set to -1, the filter is disabled.
|
|
||||||
Only used if the output format is mp3.
|
|
||||||
.TP
|
|
||||||
.I highpass
|
|
||||||
Highpass filter setting for the lame encoder, in Hz. Frequencies below
|
|
||||||
the specified value will be cut.
|
|
||||||
If not set or set to 0, the encoder's default behaviour is used.
|
|
||||||
If set to -1, the filter is disabled.
|
|
||||||
Only used if the output format is mp3.
|
|
||||||
|
|
||||||
.PP
|
|
||||||
A sample configuration file follows. This file makes
|
|
||||||
.B DarkIce
|
|
||||||
stream for 1 minute (60 seconds) from the audio device
|
|
||||||
.I /dev/dsp
|
|
||||||
at 22.05kHz, 16 bit stereo.
|
|
||||||
It will build up a connection to the
|
|
||||||
.B IceCast
|
|
||||||
server yp.yourserver.com on port 8000 with the password "hackme".
|
|
||||||
The stream will be encoded to 96 kb/s mp3 with quality 0.8, and will be
|
|
||||||
reachable at
|
|
||||||
.I http://yp.yourserver.com:8000/live96
|
|
||||||
to mp3 players.
|
|
||||||
The encoding session will be stored by
|
|
||||||
.B IceCast
|
|
||||||
in the file
|
|
||||||
.I /tmp/server-dump.mp3
|
|
||||||
on the server side, and also by
|
|
||||||
.B DarkIce
|
|
||||||
in the file
|
|
||||||
.I /tmp/encoder-dump.mp3
|
|
||||||
on the encoder side.
|
|
||||||
|
|
||||||
.nf
|
|
||||||
[general]
|
|
||||||
duration = 60
|
|
||||||
bufferSecs = 5
|
|
||||||
|
|
||||||
[input]
|
|
||||||
device = /dev/dsp
|
|
||||||
sampleRate = 22050
|
|
||||||
bitsPerSample = 16
|
|
||||||
channel = 2
|
|
||||||
|
|
||||||
[icecast-0]
|
|
||||||
bitrateMode = cbr
|
|
||||||
bitrate = 96
|
|
||||||
quality = 0.8
|
|
||||||
server = yp.yourserver.com
|
|
||||||
port = 8000
|
|
||||||
password = hackme
|
|
||||||
mountPoint = live96
|
|
||||||
name = DarkIce trial
|
|
||||||
description = This is only a trial
|
|
||||||
url = http://www.yourserver.com
|
|
||||||
genre = live
|
|
||||||
public = no
|
|
||||||
remoteDumpFile = /tmp/server-dump.mp3
|
|
||||||
localDumpFile = /tmp/encoder-dump.mp3
|
|
||||||
fileAddDate = no
|
|
||||||
.fi
|
|
||||||
|
|
||||||
|
|
||||||
.PP
|
|
||||||
The following sample configuration file simply encodes the 16 bit stereo
|
|
||||||
44.1 kHz sound card input into Ogg Vorbis at average bit rate 96 kb/s for 60
|
|
||||||
seconds, and saves it in the local file at /tmp/save.ogg.
|
|
||||||
|
|
||||||
.nf
|
|
||||||
[general]
|
|
||||||
duration = 60
|
|
||||||
bufferSecs = 5
|
|
||||||
|
|
||||||
[input]
|
|
||||||
device = /dev/dsp
|
|
||||||
sampleRate = 44100
|
|
||||||
bitsPerSample = 16
|
|
||||||
channel = 2
|
|
||||||
|
|
||||||
[file-0]
|
|
||||||
format = vorbis
|
|
||||||
bitrateMode = abr
|
|
||||||
bitrate = 96
|
|
||||||
fileName = /tmp/save.ogg
|
|
||||||
.fi
|
|
||||||
|
|
||||||
|
|
||||||
.PP
|
|
||||||
A bit more complicated sample follows. This one makes
|
|
||||||
.B DarkIce
|
|
||||||
stream for 1 hour (3600 seconds) from the audio device
|
|
||||||
.I /dev/dsp
|
|
||||||
at 44.1kHz, 16 bit stereo.
|
|
||||||
|
|
||||||
It will build up a connection to an
|
|
||||||
.B IceCast
|
|
||||||
server yp.your-ice-server.com on port 8000 with the password "ice-hackme".
|
|
||||||
The sound for this stream will be cut at 10500 Hz from above.
|
|
||||||
The stream will be encoded to average bit rate 96 kb/s mp3 and resampled to
|
|
||||||
22.05kHz and 1 channel (mono).
|
|
||||||
The stream will be reachable at
|
|
||||||
.I http://yp.your-ice-server.com:8000/live96
|
|
||||||
to mp3 players.
|
|
||||||
The encoding session will be stored by
|
|
||||||
.B IceCast
|
|
||||||
in the file
|
|
||||||
.I /tmp/live96.mp3
|
|
||||||
on the server side.
|
|
||||||
|
|
||||||
It will also connect to a
|
|
||||||
.I ShoutCast
|
|
||||||
server at yp.your-shout-server.com on port 8001 with the password "shout-hackme"
|
|
||||||
This stream will be encoded to constant bit rate 128 kb/s mp3 with quality
|
|
||||||
0.8, and will be reachable at
|
|
||||||
.I http://yp.your-shout-server.com:8000
|
|
||||||
to mp3 players.
|
|
||||||
|
|
||||||
.nf
|
|
||||||
[general]
|
|
||||||
duration = 3600
|
|
||||||
bufferSecs = 5
|
|
||||||
|
|
||||||
[input]
|
|
||||||
device = /dev/dsp
|
|
||||||
sampleRate = 22050
|
|
||||||
bitsPerSample = 16
|
|
||||||
channel = 2
|
|
||||||
|
|
||||||
[icecast-0]
|
|
||||||
sampleRate = 22050
|
|
||||||
channel = 1
|
|
||||||
bitrateMode = abr
|
|
||||||
bitrate = 96
|
|
||||||
lowpass = 10500
|
|
||||||
server = yp.your-ice-server.com
|
|
||||||
port = 8000
|
|
||||||
password = ice-hackme
|
|
||||||
mountPoint = live96
|
|
||||||
name = DarkIce trial
|
|
||||||
description = This is only a trial
|
|
||||||
url = http://www.yourserver.com
|
|
||||||
genre = live
|
|
||||||
public = yes
|
|
||||||
remoteDumpFile = /tmp/live96.mp3
|
|
||||||
|
|
||||||
[shoutcast-0]
|
|
||||||
bitrateMode = cbr
|
|
||||||
bitrate = 128
|
|
||||||
quality = 0.8
|
|
||||||
server = yp.your-shout-server.com
|
|
||||||
port = 8001
|
|
||||||
password = shout-hackme
|
|
||||||
name = DarkIce trial
|
|
||||||
url = http://www.yourserver.com
|
|
||||||
genre = live
|
|
||||||
public = yes
|
|
||||||
irc = irc.yourserver.com
|
|
||||||
aim = aim here
|
|
||||||
icq = I see you too
|
|
||||||
.fi
|
|
||||||
|
|
||||||
|
|
||||||
.SH BUGS
|
|
||||||
.PP
|
|
||||||
Lots of bugs.
|
|
||||||
|
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
darkice(1)
|
|
||||||
|
|
||||||
|
|
||||||
.SH AUTHOR
|
|
||||||
Akos Maroy
|
|
||||||
.I <darkeye@tyrell.hu>
|
|
||||||
|
|
||||||
|
|
||||||
.SH LINKS
|
|
||||||
Project homepage:
|
|
||||||
.I http://darkice.tyrell.hu/
|
|
||||||
|
|
||||||
.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/
|
|
|
@ -1,190 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
# Common stub for a few missing GNU programs while installing.
|
|
||||||
# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
|
||||||
# Franc,ois Pinard <pinard@iro.umontreal.ca>, 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
|
|
|
@ -1,40 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
# mkinstalldirs --- make directory hierarchy
|
|
||||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
|
||||||
# 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
|
|
|
@ -1,290 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Copyright (c) 2004
|
|
||||||
LS Informationstechnik (LIKE)
|
|
||||||
University of Erlangen Nuremberg
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : AlsaDspSource.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#include "AudioSource.h"
|
|
||||||
|
|
||||||
// compile only if configured for ALSA
|
|
||||||
#ifdef SUPPORT_ALSA_DSP
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Util.h"
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "AlsaDspSource.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Tell if source id big endian
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
AlsaDspSource :: isBigEndian ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return SND_PCM_FORMAT_S16 == SND_PCM_FORMAT_S16_BE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
AlsaDspSource :: init ( const char * name ) throw ( Exception )
|
|
||||||
{
|
|
||||||
pcmName = Util::strDup( name);
|
|
||||||
captureHandle = 0;
|
|
||||||
bufferTime = 1000000; // Do 1s buffering
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* De-initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
AlsaDspSource :: strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] pcmName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Open the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
AlsaDspSource :: open ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
unsigned int u;
|
|
||||||
snd_pcm_format_t format;
|
|
||||||
snd_pcm_hw_params_t *hwParams;
|
|
||||||
|
|
||||||
if ( isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( getBitsPerSample() ) {
|
|
||||||
case 8:
|
|
||||||
format = SND_PCM_FORMAT_S8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 16:
|
|
||||||
format = SND_PCM_FORMAT_S16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (snd_pcm_open(&captureHandle, pcmName, SND_PCM_STREAM_CAPTURE, 0) < 0) {
|
|
||||||
captureHandle = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (snd_pcm_hw_params_malloc(&hwParams) < 0) {
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "can't alloc hardware "\
|
|
||||||
"parameter structure");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (snd_pcm_hw_params_any(captureHandle, hwParams) < 0) {
|
|
||||||
snd_pcm_hw_params_free(hwParams);
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "can't initialize hardware "\
|
|
||||||
"parameter structure");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (snd_pcm_hw_params_set_access(captureHandle, hwParams,
|
|
||||||
SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
|
|
||||||
snd_pcm_hw_params_free(hwParams);
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "can't set access type");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (snd_pcm_hw_params_set_format(captureHandle, hwParams, format) < 0) {
|
|
||||||
snd_pcm_hw_params_free(hwParams);
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "can't set sample format");
|
|
||||||
}
|
|
||||||
|
|
||||||
u = getSampleRate();
|
|
||||||
if (snd_pcm_hw_params_set_rate_near(captureHandle, hwParams, &u, 0) < 0) {
|
|
||||||
snd_pcm_hw_params_free(hwParams);
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "can't set sample rate", u);
|
|
||||||
}
|
|
||||||
|
|
||||||
u = getChannel();
|
|
||||||
if (snd_pcm_hw_params_set_channels(captureHandle, hwParams, u) < 0) {
|
|
||||||
snd_pcm_hw_params_free(hwParams);
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "can't set channels", u);
|
|
||||||
}
|
|
||||||
|
|
||||||
u = getBufferTime() / 4;
|
|
||||||
if (snd_pcm_hw_params_set_period_time_near(captureHandle, hwParams, &u, 0)
|
|
||||||
< 0) {
|
|
||||||
snd_pcm_hw_params_free(hwParams);
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "can't set interrupt frequency");
|
|
||||||
}
|
|
||||||
|
|
||||||
u = getBufferTime();
|
|
||||||
if (snd_pcm_hw_params_set_buffer_time_near(captureHandle, hwParams, &u, 0)
|
|
||||||
< 0) {
|
|
||||||
snd_pcm_hw_params_free(hwParams);
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "can't set buffer size");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (snd_pcm_hw_params(captureHandle, hwParams) < 0) {
|
|
||||||
snd_pcm_hw_params_free(hwParams);
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "can't set hardware parameters");
|
|
||||||
}
|
|
||||||
|
|
||||||
snd_pcm_hw_params_free(hwParams);
|
|
||||||
|
|
||||||
if (snd_pcm_prepare(captureHandle) < 0) {
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "can't prepare audio interface "\
|
|
||||||
"for use");
|
|
||||||
}
|
|
||||||
|
|
||||||
bytesPerFrame = getChannel() * getBitsPerSample() / 8;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Check wether read() would return anything
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
AlsaDspSource :: canRead ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !running ) {
|
|
||||||
snd_pcm_start(captureHandle);
|
|
||||||
running = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME How to check for available frames? It
|
|
||||||
* seems like snd_pcm_wait stops working when
|
|
||||||
* it comes to ALSA plugins... :-(
|
|
||||||
*
|
|
||||||
* int milliDelay = sec * 1000 + usec/1000;
|
|
||||||
* return snd_pcm_wait(captureHandle, milliDelay)!=0;
|
|
||||||
*/
|
|
||||||
return true; // bad!!
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Read from the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
AlsaDspSource :: read ( void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
snd_pcm_sframes_t ret;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
ret = snd_pcm_readi(captureHandle, buf, len/bytesPerFrame);
|
|
||||||
|
|
||||||
// Check for buffer overrun
|
|
||||||
if (ret == -EPIPE) {
|
|
||||||
reportEvent(1, "Buffer overrun!");
|
|
||||||
snd_pcm_prepare(captureHandle);
|
|
||||||
ret = -EAGAIN;
|
|
||||||
}
|
|
||||||
} while (ret == -EAGAIN);
|
|
||||||
|
|
||||||
if ( ret < 0 ) {
|
|
||||||
throw Exception(__FILE__, __LINE__, snd_strerror(ret));
|
|
||||||
}
|
|
||||||
|
|
||||||
running = true;
|
|
||||||
return ret * bytesPerFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Close the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
AlsaDspSource :: close ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
snd_pcm_close(captureHandle);
|
|
||||||
|
|
||||||
captureHandle = 0;
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // HAVE_ALSA_LIB
|
|
||||||
|
|
|
@ -1,299 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Copyright (c) 2004
|
|
||||||
LS Informationstechnik (LIKE)
|
|
||||||
University of Erlangen Nuremberg
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : AlsaDspSource.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
#ifndef ALSA_SOURCE_H
|
|
||||||
#define ALSA_SOURCE_H
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#error This is a C++ include file
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Reporter.h"
|
|
||||||
#include "AudioSource.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_ALSA_LIB
|
|
||||||
#include <alsa/asoundlib.h>
|
|
||||||
#else
|
|
||||||
#error configure for ALSA
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An audio input based on the ALSA sound system
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class AlsaDspSource : public AudioSource, public virtual Reporter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Name of the capture PCM stream.
|
|
||||||
*/
|
|
||||||
char *pcmName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle to access PCM stream data.
|
|
||||||
*/
|
|
||||||
snd_pcm_t *captureHandle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores number of bytes per frame. One frame
|
|
||||||
* contains all samples per time instance.
|
|
||||||
*/
|
|
||||||
int bytesPerFrame;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is the stream running?
|
|
||||||
*/
|
|
||||||
bool running;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of useconds to do buffering in the audio device.
|
|
||||||
*/
|
|
||||||
unsigned int bufferTime;
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
AlsaDspSource ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object
|
|
||||||
*
|
|
||||||
* @param name the PCM to open.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( const char * name ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-iitialize the object
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
strip ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param name the PCM (e.g. "hwplug:0,0").
|
|
||||||
* @param sampleRate samples per second (e.g. 44100 for 44.1kHz).
|
|
||||||
* @param bitsPerSample bits per sample (e.g. 16 bits).
|
|
||||||
* @param channel number of channels of the audio source
|
|
||||||
* (e.g. 1 for mono, 2 for stereo, etc.).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
AlsaDspSource ( const char * name,
|
|
||||||
int sampleRate = 44100,
|
|
||||||
int bitsPerSample = 16,
|
|
||||||
int channel = 2 )
|
|
||||||
throw ( Exception )
|
|
||||||
: AudioSource( sampleRate, bitsPerSample, channel)
|
|
||||||
{
|
|
||||||
init( name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy Constructor.
|
|
||||||
*
|
|
||||||
* @param ds the object to copy.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
AlsaDspSource ( const AlsaDspSource & ds ) throw ( Exception )
|
|
||||||
: AudioSource( ds )
|
|
||||||
{
|
|
||||||
init( ds.pcmName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~AlsaDspSource ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param ds the object to assign to this one.
|
|
||||||
* @return a reference to this object.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual AlsaDspSource &
|
|
||||||
operator= ( const AlsaDspSource & ds ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &ds ) {
|
|
||||||
strip();
|
|
||||||
AudioSource::operator=( ds);
|
|
||||||
init( ds.pcmName);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tell if the data from this source comes in big or little endian.
|
|
||||||
*
|
|
||||||
* @return true if the source is big endian, false otherwise
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
isBigEndian ( void ) const throw ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open the AlsaDspSource.
|
|
||||||
* This does not put Alsa device into recording mode.
|
|
||||||
* To start getting samples, call either canRead() or read().
|
|
||||||
*
|
|
||||||
* @return true if opening was successful, false otherwise
|
|
||||||
* @exception Exception
|
|
||||||
*
|
|
||||||
* @see #canRead
|
|
||||||
* @see #read
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
open ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the AlsaDspSource is open.
|
|
||||||
*
|
|
||||||
* @return true if the AlsaDspSource is open, false otherwise.
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isOpen ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return captureHandle != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the AlsaDspSource can be read from.
|
|
||||||
* Blocks until the specified time for data to be available.
|
|
||||||
* Puts the PCM into recording mode.
|
|
||||||
*
|
|
||||||
* @param sec the maximum seconds to block.
|
|
||||||
* @param usec micro seconds to block after the full seconds.
|
|
||||||
* @return true if the AlsaDspSource is ready to be read from,
|
|
||||||
* false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
canRead ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read from the AlsaDspSource.
|
|
||||||
* Puts the PCM into recording mode.
|
|
||||||
*
|
|
||||||
* @param buf the buffer to read into.
|
|
||||||
* @param len the number of bytes to read into buf
|
|
||||||
* @return the number of bytes read (may be less than len).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual unsigned int
|
|
||||||
read ( void * buf,
|
|
||||||
unsigned int len ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the AlsaDspSource.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
close ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the buffer size in useconds.
|
|
||||||
*
|
|
||||||
* @return the number of useconds audio will be buffered in ALSA
|
|
||||||
*/
|
|
||||||
inline virtual unsigned int
|
|
||||||
getBufferTime( void ) const
|
|
||||||
{
|
|
||||||
return bufferTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the number of useconds to buffer audio in ALSA
|
|
||||||
*
|
|
||||||
* @param time buffer time
|
|
||||||
*/
|
|
||||||
inline virtual void
|
|
||||||
setBufferTime( unsigned int time ) {
|
|
||||||
bufferTime = time;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ALSA_SOURCE_H */
|
|
||||||
|
|
|
@ -1,493 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : AudioEncoder.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Sink to dump the encoded data to
|
|
||||||
*/
|
|
||||||
Ref<Sink> sink;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 sink the sink to send encoded output to
|
|
||||||
* @param inSampleRate sample rate of the input.
|
|
||||||
* @param inBitsPerSample number of bits per sample of the input.
|
|
||||||
* @param inChannel number of channels of the input.
|
|
||||||
* @param inBigEndian shows if the input is big or little endian.
|
|
||||||
* @param outBitrateMode the bit rate mode of the output.
|
|
||||||
* @param outBitrate bit rate of the output.
|
|
||||||
* @param outSampleRate sample rate of the output.
|
|
||||||
* @param outChannel number of channels of the output.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline void
|
|
||||||
init ( Sink * sink,
|
|
||||||
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->sink = sink;
|
|
||||||
this->inSampleRate = inSampleRate;
|
|
||||||
this->inBitsPerSample = inBitsPerSample;
|
|
||||||
this->inChannel = inChannel;
|
|
||||||
this->inBigEndian = inBigEndian;
|
|
||||||
this->outBitrateMode = outBitrateMode;
|
|
||||||
this->outBitrate = outBitrate;
|
|
||||||
this->outQuality = outQuality;
|
|
||||||
this->outSampleRate = outSampleRate;
|
|
||||||
this->outChannel = outChannel;
|
|
||||||
|
|
||||||
if ( outQuality < -0.1 || 1.0 < outQuality ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "invalid encoder quality");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-iitialize the object.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline void
|
|
||||||
strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
AudioEncoder ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param sink the sink to send encoded output to
|
|
||||||
* @param inSampleRate sample rate of the input.
|
|
||||||
* @param inBitsPerSample number of bits per sample of the input.
|
|
||||||
* @param inChannel number of channels of the input.
|
|
||||||
* @param inBigEndian shows if the input is big or little endian
|
|
||||||
* @param outBitrateMode the bit rate mode of the output.
|
|
||||||
* @param outBitrate bit rate of the output (kbits/sec).
|
|
||||||
* @param outQuality the quality of the stream.
|
|
||||||
* @param outSampleRate sample rate of the output.
|
|
||||||
* If 0, inSampleRate is used.
|
|
||||||
* @param outChannel number of channels of the output.
|
|
||||||
* If 0, inChannel is used.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
AudioEncoder ( 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 )
|
|
||||||
{
|
|
||||||
init ( sink,
|
|
||||||
inSampleRate,
|
|
||||||
inBitsPerSample,
|
|
||||||
inChannel,
|
|
||||||
inBigEndian,
|
|
||||||
outBitrateMode,
|
|
||||||
outBitrate,
|
|
||||||
outQuality,
|
|
||||||
outSampleRate ? outSampleRate : inSampleRate,
|
|
||||||
outChannel ? outChannel : inChannel );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param sink the sink to send encoded output to
|
|
||||||
* @param as get input sample rate, bits per sample and channels
|
|
||||||
* from this AudioSource.
|
|
||||||
* @param outBitrateMode the bit rate mode of the output.
|
|
||||||
* @param outBitrate bit rate of the output (kbits/sec).
|
|
||||||
* @param outQuality the quality of the stream.
|
|
||||||
* @param outSampleRate sample rate of the output.
|
|
||||||
* If 0, input sample rate is used.
|
|
||||||
* @param outChannel number of channels of the output.
|
|
||||||
* If 0, input channel is used.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
AudioEncoder ( Sink * sink,
|
|
||||||
const AudioSource * as,
|
|
||||||
BitrateMode outBitrateMode,
|
|
||||||
unsigned int outBitrate,
|
|
||||||
double outQuality,
|
|
||||||
unsigned int outSampleRate = 0,
|
|
||||||
unsigned int outChannel = 0 )
|
|
||||||
throw ( Exception)
|
|
||||||
{
|
|
||||||
init( sink,
|
|
||||||
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.sink.get(),
|
|
||||||
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.sink.get(),
|
|
||||||
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 underlying sink, that the encoded content is sent to.
|
|
||||||
*
|
|
||||||
* @return the underlying sink
|
|
||||||
*/
|
|
||||||
inline virtual Ref<Sink>
|
|
||||||
getSink(void) throw ()
|
|
||||||
{
|
|
||||||
return sink;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of channels of the input.
|
|
||||||
*
|
|
||||||
* @return the number of channels of the input.
|
|
||||||
*/
|
|
||||||
inline int
|
|
||||||
getInChannel ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return inChannel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tell if the input is big or little endian.
|
|
||||||
*
|
|
||||||
* @return true if the input is big endian, false if little endian.
|
|
||||||
*/
|
|
||||||
inline bool
|
|
||||||
isInBigEndian ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return inBigEndian;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the sample rate of the input.
|
|
||||||
*
|
|
||||||
* @return the sample rate of the input.
|
|
||||||
*/
|
|
||||||
inline int
|
|
||||||
getInSampleRate ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return inSampleRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of bits per sample of the input.
|
|
||||||
*
|
|
||||||
* @return the number of bits per sample of the input.
|
|
||||||
*/
|
|
||||||
inline int
|
|
||||||
getInBitsPerSample ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return inBitsPerSample;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of channels of the output.
|
|
||||||
*
|
|
||||||
* @return the number of channels of the output.
|
|
||||||
*/
|
|
||||||
inline int
|
|
||||||
getOutChannel ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return outChannel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the sample rate of the output.
|
|
||||||
*
|
|
||||||
* @return the sample rate of the output.
|
|
||||||
*/
|
|
||||||
inline int
|
|
||||||
getOutSampleRate ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return outSampleRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the bit rate mode of the output.
|
|
||||||
*
|
|
||||||
* @return the bit rate mode of the output.
|
|
||||||
*/
|
|
||||||
inline BitrateMode
|
|
||||||
getOutBitrateMode ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return outBitrateMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the bit rate of the output in kbits/sec, for fixed bitrate
|
|
||||||
* encodings.
|
|
||||||
*
|
|
||||||
* @return the bit rate of the output.
|
|
||||||
*/
|
|
||||||
inline unsigned int
|
|
||||||
getOutBitrate ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return outBitrate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the encoding quality of the output, for variable bitrate
|
|
||||||
* encodings.
|
|
||||||
*
|
|
||||||
* @return the encoding quality of the output.
|
|
||||||
*/
|
|
||||||
inline double
|
|
||||||
getOutQuality ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return outQuality;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check wether encoding is in progress.
|
|
||||||
*
|
|
||||||
* @return true if encoding is in progress, false otherwise.
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
isRunning ( void ) const throw () = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start encoding. This function returns as soon as possible,
|
|
||||||
* with encoding started in the background.
|
|
||||||
*
|
|
||||||
* @return true if encoding has started, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
start ( void ) throw ( Exception ) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop encoding. Stops the encoding running in the background.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
stop ( void ) throw ( Exception ) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cut what the sink has been doing so far, and start anew.
|
|
||||||
* This usually means separating the data sent to the sink up
|
|
||||||
* until now, and start saving a new chunk of data.
|
|
||||||
*
|
|
||||||
* Typically this action is delegated to the underlying sink.
|
|
||||||
*/
|
|
||||||
inline virtual void
|
|
||||||
cut ( void ) throw ()
|
|
||||||
{
|
|
||||||
sink->cut();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* AUDIO_ENCODER_H */
|
|
||||||
|
|
|
@ -1,128 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : AudioSource.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "AudioSource.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "Exception.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Return an audio source based on the compiled DSP supports and the
|
|
||||||
* supplied device name parameter.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
AudioSource *
|
|
||||||
AudioSource :: createDspSource( const char * deviceName,
|
|
||||||
const char * jackClientName,
|
|
||||||
int sampleRate,
|
|
||||||
int bitsPerSample,
|
|
||||||
int channel)
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
|
|
||||||
if ( Util::strEq( deviceName, "/dev/tty", 8) ) {
|
|
||||||
#if defined( SUPPORT_SERIAL_ULAW )
|
|
||||||
Reporter::reportEvent( 1, "Using Serial Ulaw input device:",
|
|
||||||
deviceName);
|
|
||||||
return new SerialUlaw( deviceName,
|
|
||||||
sampleRate,
|
|
||||||
bitsPerSample,
|
|
||||||
channel);
|
|
||||||
#else
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"trying to open Serial ULaw device "
|
|
||||||
"without support compiled", deviceName);
|
|
||||||
#endif
|
|
||||||
} else if ( Util::strEq( deviceName, "/dev", 4) ) {
|
|
||||||
#if defined( SUPPORT_OSS_DSP )
|
|
||||||
Reporter::reportEvent( 1, "Using OSS DSP input device:", deviceName);
|
|
||||||
return new OssDspSource( deviceName,
|
|
||||||
sampleRate,
|
|
||||||
bitsPerSample,
|
|
||||||
channel);
|
|
||||||
#elif defined( SUPPORT_SOLARIS_DSP )
|
|
||||||
Reporter::reportEvent( 1, "Using Solaris DSP input device:",deviceName);
|
|
||||||
return new SolarisDspSource( deviceName,
|
|
||||||
sampleRate,
|
|
||||||
bitsPerSample,
|
|
||||||
channel);
|
|
||||||
#else
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"trying to open OSS or Solaris DSP device "
|
|
||||||
"without support compiled", deviceName);
|
|
||||||
#endif
|
|
||||||
} else if ( Util::strEq( deviceName, "jack", 4) ) {
|
|
||||||
#if defined( SUPPORT_JACK_DSP )
|
|
||||||
Reporter::reportEvent( 1, "Using JACK audio server as input device.");
|
|
||||||
return new JackDspSource( deviceName,
|
|
||||||
jackClientName,
|
|
||||||
sampleRate,
|
|
||||||
bitsPerSample,
|
|
||||||
channel);
|
|
||||||
#else
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"trying to open JACK device without "
|
|
||||||
"support compiled", deviceName);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#if defined( SUPPORT_ALSA_DSP )
|
|
||||||
Reporter::reportEvent( 1, "Using ALSA DSP input device:", deviceName);
|
|
||||||
return new AlsaDspSource( deviceName,
|
|
||||||
sampleRate,
|
|
||||||
bitsPerSample,
|
|
||||||
channel);
|
|
||||||
#else
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"trying to open ALSA DSP device without "
|
|
||||||
"support compiled", deviceName);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,314 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : AudioSource.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
#ifndef AUDIO_SOURCE_H
|
|
||||||
#define AUDIO_SOURCE_H
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#error This is a C++ include file
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#include "Source.h"
|
|
||||||
#include "Reporter.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Determine the kind of audio device based on the system
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
#if defined( HAVE_ALSA_LIB )
|
|
||||||
// we have an ALSA sound system available
|
|
||||||
#define SUPPORT_ALSA_DSP 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined( HAVE_SYS_SOUNDCARD_H )
|
|
||||||
// we have an OSS DSP sound source device available
|
|
||||||
#define SUPPORT_OSS_DSP 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined( HAVE_SYS_AUDIO_H ) || defined( HAVE_SYS_AUDIOIO_H )
|
|
||||||
// we have a Solaris DSP sound device available (same for OpenBSD)
|
|
||||||
#define SUPPORT_SOLARIS_DSP 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined( HAVE_JACK_LIB )
|
|
||||||
// we have JACK audio server
|
|
||||||
#define SUPPORT_JACK_DSP 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined ( HAVE_TERMIOS_H )
|
|
||||||
#define SUPPORT_SERIAL_ULAW 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined( SUPPORT_ALSA_DSP ) \
|
|
||||||
&& !defined( SUPPORT_OSS_DSP ) \
|
|
||||||
&& !defined( SUPPORT_JACK_DSP ) \
|
|
||||||
&& !defined( SUPPORT_SOLARIS_DSP ) \
|
|
||||||
&& !defined( SUPPORT_SERIAL_ULAW)
|
|
||||||
// there was no DSP audio system found
|
|
||||||
#error No DSP audio input device found on system
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Audio data input
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class AudioSource : public Source, public virtual Reporter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of channels of the audio source
|
|
||||||
* (e.g. 1 for mono, 2 for stereo, etc.)
|
|
||||||
*/
|
|
||||||
unsigned int channel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Samples per second (e.g. 44100 for 44.1kHz CD quality)
|
|
||||||
*/
|
|
||||||
unsigned int sampleRate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bits per sample (e.g. 8 bits, 16 bits, etc.)
|
|
||||||
*/
|
|
||||||
unsigned int bitsPerSample;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object.
|
|
||||||
*
|
|
||||||
* @param sampleRate samples per second.
|
|
||||||
* @param bitsPerSample bits per sample.
|
|
||||||
* @param channel number of channels of the audio source.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline void
|
|
||||||
init ( unsigned int sampleRate,
|
|
||||||
unsigned int bitsPerSample,
|
|
||||||
unsigned int channel ) throw ( Exception )
|
|
||||||
{
|
|
||||||
this->sampleRate = sampleRate;
|
|
||||||
this->bitsPerSample = bitsPerSample;
|
|
||||||
this->channel = channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-initialize the object.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline void
|
|
||||||
strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
* Because all values have defaults, this is also the default
|
|
||||||
* constructor.
|
|
||||||
*
|
|
||||||
* @param sampleRate samples per second (e.g. 44100 for 44.1kHz).
|
|
||||||
* @param bitsPerSample bits per sample (e.g. 16 bits).
|
|
||||||
* @param channel number of channels of the audio source
|
|
||||||
* (e.g. 1 for mono, 2 for stereo, etc.).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
AudioSource ( unsigned int sampleRate = 44100,
|
|
||||||
unsigned int bitsPerSample = 16,
|
|
||||||
unsigned int channel = 2 )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
init ( sampleRate, bitsPerSample, channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy Constructor.
|
|
||||||
*
|
|
||||||
* @param as the object to copy.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
AudioSource ( const AudioSource & as ) throw ( Exception )
|
|
||||||
: Source( as )
|
|
||||||
{
|
|
||||||
init ( as.sampleRate, as.bitsPerSample, as.channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param as the object to assign to this one.
|
|
||||||
* @return a reference to this object.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual AudioSource &
|
|
||||||
operator= ( const AudioSource & as ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &as ) {
|
|
||||||
strip();
|
|
||||||
Source::operator=( as );
|
|
||||||
init ( as.sampleRate, as.bitsPerSample, as.channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual inline
|
|
||||||
~AudioSource ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of channels for this AudioSource.
|
|
||||||
*
|
|
||||||
* @return the number of channels.
|
|
||||||
*/
|
|
||||||
inline unsigned int
|
|
||||||
getChannel ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tell if the data from this source comes in big or little endian.
|
|
||||||
*
|
|
||||||
* @return true if the data is big endian, false if little endian
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
isBigEndian ( void ) const throw ()
|
|
||||||
{
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the sample rate per seconds for this AudioSource.
|
|
||||||
*
|
|
||||||
* @return the sample rate per seconds.
|
|
||||||
*/
|
|
||||||
inline unsigned int
|
|
||||||
getSampleRate ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return sampleRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of bits per sample for this AudioSource.
|
|
||||||
*
|
|
||||||
* @return the number of bits per sample.
|
|
||||||
*/
|
|
||||||
inline unsigned int
|
|
||||||
getBitsPerSample ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return bitsPerSample;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory method for creating an AudioSource object of the
|
|
||||||
* appropriate type, based on the compiled DSP support and
|
|
||||||
* the supplied DSP name parameter.
|
|
||||||
*
|
|
||||||
* @param deviceName the audio device (/dev/dspX, hwplug:0,0, etc)
|
|
||||||
* @param sampleRate samples per second (e.g. 44100 for 44.1kHz).
|
|
||||||
* @param bitsPerSample bits per sample (e.g. 16 bits).
|
|
||||||
* @param channel number of channels of the audio source
|
|
||||||
* (e.g. 1 for mono, 2 for stereo, etc.).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
static AudioSource *
|
|
||||||
createDspSource( const char * deviceName,
|
|
||||||
const char * jackClientName,
|
|
||||||
int sampleRate = 44100,
|
|
||||||
int bitsPerSample = 16,
|
|
||||||
int channel = 2) throw ( Exception );
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Determine the kind of audio device based on the system
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
#if defined( SUPPORT_ALSA_DSP )
|
|
||||||
#include "AlsaDspSource.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined( SUPPORT_OSS_DSP )
|
|
||||||
#include "OssDspSource.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined( SUPPORT_SOLARIS_DSP )
|
|
||||||
#include "SolarisDspSource.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined( SUPPORT_JACK_DSP )
|
|
||||||
#include "JackDspSource.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined ( SUPPORT_SERIAL_ULAW )
|
|
||||||
#include "SerialUlaw.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* AUDIO_SOURCE_H */
|
|
||||||
|
|
|
@ -1,368 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : BufferedSink.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <string.h>
|
|
||||||
#else
|
|
||||||
#error need string.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "BufferedSink.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
BufferedSink :: init ( Sink * sink,
|
|
||||||
unsigned int size,
|
|
||||||
unsigned int chunkSize ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !sink ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "no sink");
|
|
||||||
}
|
|
||||||
|
|
||||||
this->sink = sink; // create a reference
|
|
||||||
this->chunkSize = chunkSize ? chunkSize : 1;
|
|
||||||
this->bufferSize = size;
|
|
||||||
// make bufferSize a multiple of chunkSize
|
|
||||||
this->bufferSize -= this->bufferSize % this->chunkSize;
|
|
||||||
this->peak = 0;
|
|
||||||
this->misalignment = 0;
|
|
||||||
this->buffer = new unsigned char[bufferSize];
|
|
||||||
this->bufferEnd = buffer + bufferSize;
|
|
||||||
this->inp = buffer;
|
|
||||||
this->outp = buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Copy Constructor
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
BufferedSink :: BufferedSink ( const BufferedSink & buffer )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
init( buffer.sink.get(), buffer.bufferSize, buffer.chunkSize);
|
|
||||||
|
|
||||||
this->peak = buffer.peak;
|
|
||||||
this->misalignment = buffer.misalignment;
|
|
||||||
memcpy( this->buffer, buffer.buffer, this->bufferSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* De-initalize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
BufferedSink :: strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
sink = 0; // delete the reference
|
|
||||||
delete buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Assignment operator
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
BufferedSink &
|
|
||||||
BufferedSink :: operator= ( const BufferedSink & buffer )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &buffer ) {
|
|
||||||
strip();
|
|
||||||
Sink::operator=( buffer );
|
|
||||||
init( buffer.sink.get(), buffer.bufferSize, buffer.chunkSize);
|
|
||||||
|
|
||||||
this->peak = buffer.peak;
|
|
||||||
this->misalignment = buffer.misalignment;
|
|
||||||
memcpy( this->buffer, buffer.buffer, this->bufferSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Store bufferSize bytes into the buffer
|
|
||||||
* All data is consumed. The return value is less then bufferSize only
|
|
||||||
* if the BufferedSink's internal buffer is smaller than bufferSize,
|
|
||||||
* thus can't hold that much
|
|
||||||
* The data to be stored is treated as parts with chunkSize size
|
|
||||||
* Only full chunkSize sized parts are stored
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
BufferedSink :: store ( const void * buffer,
|
|
||||||
unsigned int bufferSize ) throw ( Exception )
|
|
||||||
{
|
|
||||||
const unsigned char * buf;
|
|
||||||
unsigned int size;
|
|
||||||
unsigned int i;
|
|
||||||
unsigned char * oldInp;
|
|
||||||
|
|
||||||
if ( !buffer ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "buffer is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !bufferSize ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
oldInp = inp;
|
|
||||||
buf = (const unsigned char *) buffer;
|
|
||||||
|
|
||||||
// adjust so it is a multiple of chunkSize
|
|
||||||
bufferSize -= bufferSize % chunkSize;
|
|
||||||
|
|
||||||
// cut the front of the supplied buffer if it wouldn't fit
|
|
||||||
if ( bufferSize > this->bufferSize ) {
|
|
||||||
size = this->bufferSize - 1;
|
|
||||||
size -= size % chunkSize; // keep it a multiple of chunkSize
|
|
||||||
buf += bufferSize - size;
|
|
||||||
} else {
|
|
||||||
size = bufferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy the data into the buffer
|
|
||||||
i = bufferEnd - inp;
|
|
||||||
if ( (i % chunkSize) != 0 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "copy quantity not aligned", i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( size <= i ) {
|
|
||||||
// the place between inp and bufferEnd is
|
|
||||||
// big enough to hold the data
|
|
||||||
|
|
||||||
memcpy( inp, buf, size);
|
|
||||||
inp = slidePointer( inp, size);
|
|
||||||
|
|
||||||
// adjust outp, lose the data that was overwritten, if any
|
|
||||||
if ( outp > oldInp && outp <= inp ) {
|
|
||||||
outp = slidePointer( inp, chunkSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// the place between inp and bufferEnd is not
|
|
||||||
// big enough to hold the data
|
|
||||||
// writing will take place in two turns, once from
|
|
||||||
// inp -> bufferEnd, then from buffer ->
|
|
||||||
|
|
||||||
memcpy( inp, buf, i);
|
|
||||||
i = size - i;
|
|
||||||
if ( (i % chunkSize) != 0 ) {
|
|
||||||
throw Exception(__FILE__, __LINE__, "copy quantity not aligned", i);
|
|
||||||
}
|
|
||||||
memcpy( this->buffer, buf, i);
|
|
||||||
inp = slidePointer( this->buffer, i);
|
|
||||||
|
|
||||||
// adjust outp, lose the data that was overwritten, if any
|
|
||||||
if ( outp <= oldInp ) {
|
|
||||||
if ( outp < inp ) {
|
|
||||||
outp = slidePointer( inp, chunkSize);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
outp = slidePointer( inp, chunkSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updatePeak();
|
|
||||||
|
|
||||||
if ( ((inp - this->buffer) % chunkSize) != 0 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"inp not aligned", inp - this->buffer);
|
|
||||||
}
|
|
||||||
if ( ((outp - this->buffer) % chunkSize) != 0 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"outp not aligned", outp - this->buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Write some data to the sink
|
|
||||||
* if len == 0, try to flush the buffer
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
BufferedSink :: write ( const void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
unsigned int length;
|
|
||||||
unsigned int soFar;
|
|
||||||
unsigned char * b = (unsigned char *) buf;
|
|
||||||
|
|
||||||
if ( !buf ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "buf is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !align() ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// make it a multiple of chunkSize
|
|
||||||
len -= len % chunkSize;
|
|
||||||
|
|
||||||
// try to write data from the buffer first, if any
|
|
||||||
if ( inp != outp ) {
|
|
||||||
unsigned int size = 0;
|
|
||||||
unsigned int total = 0;
|
|
||||||
|
|
||||||
if ( outp > inp ) {
|
|
||||||
// valuable data is between outp -> bufferEnd and buffer -> inp
|
|
||||||
// try to write the outp -> bufferEnd
|
|
||||||
// the rest will be written in the next if
|
|
||||||
|
|
||||||
size = bufferEnd - outp - 1;
|
|
||||||
size -= size % chunkSize;
|
|
||||||
soFar = 0;
|
|
||||||
|
|
||||||
while ( outp > inp && soFar < size && sink->canWrite( 0, 0) ) {
|
|
||||||
length = sink->write( outp + soFar, size - soFar);
|
|
||||||
outp = slidePointer( outp, length);
|
|
||||||
soFar += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
total += soFar;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( outp < inp ) {
|
|
||||||
// valuable data is between outp and inp
|
|
||||||
// in the previous if wrote all data from the end
|
|
||||||
// this part will write the rest
|
|
||||||
|
|
||||||
size = inp - outp;
|
|
||||||
soFar = 0;
|
|
||||||
|
|
||||||
while ( soFar < size && sink->canWrite( 0, 0) ) {
|
|
||||||
length = sink->write( outp + soFar, size - soFar);
|
|
||||||
outp = slidePointer( outp, length);
|
|
||||||
soFar += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
total += soFar;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ( (outp - buffer) % chunkSize ) {
|
|
||||||
slidePointer( outp, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// calulate the misalignment to chunkSize boundaries
|
|
||||||
misalignment = (chunkSize - (total % chunkSize)) % chunkSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !align() ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the internal buffer is empty, try to write the fresh data
|
|
||||||
soFar = 0;
|
|
||||||
if ( inp != outp ) {
|
|
||||||
while ( soFar < len && sink->canWrite( 0, 0) ) {
|
|
||||||
soFar += sink->write( b + soFar, len - soFar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
length = soFar;
|
|
||||||
|
|
||||||
// calulate the misalignment to chunkSize boundaries
|
|
||||||
misalignment = (chunkSize - (length % chunkSize)) % chunkSize;
|
|
||||||
|
|
||||||
if ( length < len ) {
|
|
||||||
// if not all fresh could be written, store the remains
|
|
||||||
|
|
||||||
store( b + length, len - length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// tell them we ate everything up to chunkSize alignment
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Close the sink, lose all pending data
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
BufferedSink :: close ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
flush();
|
|
||||||
sink->close();
|
|
||||||
inp = outp = buffer;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,399 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : BufferedSink.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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> sink;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object.
|
|
||||||
*
|
|
||||||
* @param sink the Sink to attach this BufferedSink to.
|
|
||||||
* @param size the size of the internal buffer to use.
|
|
||||||
* @param chunkSize size of chunks to handle data in.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( Sink * sink,
|
|
||||||
unsigned int size,
|
|
||||||
unsigned int chunkSize ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-initialize the object.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
strip ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Slide a pointer in the internal buffer by offset. If the pointer
|
|
||||||
* would reach beyond the end of the buffer, it goes wraps around.
|
|
||||||
*
|
|
||||||
* @param p the pointer to slide.
|
|
||||||
* @param offset the amount to slide with.
|
|
||||||
* @return pointer p + offset, wrapped around if needed.
|
|
||||||
*/
|
|
||||||
inline unsigned char *
|
|
||||||
slidePointer (
|
|
||||||
unsigned char * p,
|
|
||||||
unsigned int offset ) throw ()
|
|
||||||
{
|
|
||||||
p += offset;
|
|
||||||
while ( p >= bufferEnd ) {
|
|
||||||
p -= bufferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the peak buffer usage indicator.
|
|
||||||
*
|
|
||||||
* @see #peak
|
|
||||||
*/
|
|
||||||
inline void
|
|
||||||
updatePeak ( void ) throw ()
|
|
||||||
{
|
|
||||||
unsigned int u;
|
|
||||||
|
|
||||||
u = outp <= inp ? inp - outp : (bufferEnd - outp) + (inp - buffer);
|
|
||||||
if ( peak < u ) {
|
|
||||||
peak = u;
|
|
||||||
reportEvent( 4, "BufferedSink, new peak:", peak);
|
|
||||||
reportEvent( 4, "BufferedSink, remaining:", bufferSize - peak);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the underlying Sink is misaligned on chunkSize, write as
|
|
||||||
* many 0s as needed to get it aligned.
|
|
||||||
*
|
|
||||||
* @see #misalignment
|
|
||||||
* @see #chunkSize
|
|
||||||
*/
|
|
||||||
inline bool
|
|
||||||
align ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
char b[] = { 0 };
|
|
||||||
|
|
||||||
while ( misalignment ) {
|
|
||||||
if ( sink->canWrite( 0, 0) ) {
|
|
||||||
unsigned int ret;
|
|
||||||
|
|
||||||
if ( !(ret = sink->write( b, 1)) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
--misalignment;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
BufferedSink ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the size of the buffer.
|
|
||||||
*
|
|
||||||
* @return the size of the buffer.
|
|
||||||
*/
|
|
||||||
inline unsigned int
|
|
||||||
getSize ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return bufferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store data in the internal buffer. If there is not enough space,
|
|
||||||
* discard all in the buffer and the beginning of the supplied
|
|
||||||
* buffer if needed.
|
|
||||||
*
|
|
||||||
* @param buffer the data to store.
|
|
||||||
* @param bufferSize the amount of data to store in bytes.
|
|
||||||
* @return number of bytes really stored.
|
|
||||||
*/
|
|
||||||
unsigned int
|
|
||||||
store ( const void * buffer,
|
|
||||||
unsigned int bufferSize ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor by an underlying Sink, buffer size and chunk size.
|
|
||||||
*
|
|
||||||
* @param sink the Sink to attach this BufferSink to.
|
|
||||||
* @param size the size of the buffer to use for buffering.
|
|
||||||
* @param chunkSize hanlde all data in write() as chunks of
|
|
||||||
* chunkSize
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
BufferedSink ( Sink * sink,
|
|
||||||
unsigned int size,
|
|
||||||
unsigned int chunkSize = 1 ) throw ( Exception )
|
|
||||||
{
|
|
||||||
init( sink, size, chunkSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor.
|
|
||||||
*
|
|
||||||
* @param buffer the object to copy.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
BufferedSink ( const BufferedSink & buffer ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~BufferedSink ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param bs the object to assign to this one.
|
|
||||||
* @return a reference to this object.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual BufferedSink &
|
|
||||||
operator= ( const BufferedSink & bs ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the peak usage of the internal buffer.
|
|
||||||
*
|
|
||||||
* @return the peak usage of the internal buffer.
|
|
||||||
*/
|
|
||||||
inline unsigned int
|
|
||||||
getPeak ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return peak;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open the BufferedSink. Opens the underlying Sink.
|
|
||||||
*
|
|
||||||
* @return true if opening was successful, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
open ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
return sink->open();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a BufferedSink is open.
|
|
||||||
*
|
|
||||||
* @return true if the BufferedSink is open, false otherwise.
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isOpen ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return sink->isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the BufferedSink is ready to accept data.
|
|
||||||
* Always returns true immediately.
|
|
||||||
*
|
|
||||||
* @param sec the maximum seconds to block.
|
|
||||||
* @param usec micro seconds to block after the full seconds.
|
|
||||||
* @return true
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
canWrite ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write data to the BufferedSink.
|
|
||||||
* Always reads the maximum number of chunkSize chunks buf
|
|
||||||
* holds. If the data can not be written to the underlying
|
|
||||||
* stream, it is buffered. If the buffer overflows, the oldest
|
|
||||||
* data is discarded.
|
|
||||||
*
|
|
||||||
* @param buf the data to write.
|
|
||||||
* @param len number of bytes to write from buf.
|
|
||||||
* @return the number of bytes written (may be less than len).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual unsigned int
|
|
||||||
write ( const void * buf,
|
|
||||||
unsigned int len ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush all data that was written to the BufferedSink to the
|
|
||||||
* underlying Sink.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual void
|
|
||||||
flush ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
unsigned char b[1];
|
|
||||||
|
|
||||||
write( b, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cut what the sink has been doing so far, and start anew.
|
|
||||||
* This usually means separating the data sent to the sink up
|
|
||||||
* until now, and start saving a new chunk of data.
|
|
||||||
*/
|
|
||||||
inline virtual void
|
|
||||||
cut ( void ) throw ()
|
|
||||||
{
|
|
||||||
flush();
|
|
||||||
sink->cut();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the BufferedSink. Closes the underlying Sink.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
close ( void ) throw ( Exception );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BUFFERED_SINK_H */
|
|
||||||
|
|
|
@ -1,141 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : CastSink.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,480 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : CastSink.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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<TcpSocket> socket;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The BufferedSink encapsulating the socket connection to the server.
|
|
||||||
*/
|
|
||||||
Ref<BufferedSink> bufferedSink;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An optional Sink to enable stream dumps.
|
|
||||||
*/
|
|
||||||
Ref<Sink> streamDump;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Duration of the BufferedSink buffer in seconds.
|
|
||||||
*/
|
|
||||||
unsigned int bufferDuration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Password to the server.
|
|
||||||
*/
|
|
||||||
char * password;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Name of the stream.
|
|
||||||
*/
|
|
||||||
char * name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* URL associated with the stream.
|
|
||||||
*/
|
|
||||||
char * url;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Genre of the stream.
|
|
||||||
*/
|
|
||||||
char * genre;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bitrate of the stream (e.g. mp3 bitrate).
|
|
||||||
*/
|
|
||||||
unsigned int bitRate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is the stream public?
|
|
||||||
*/
|
|
||||||
bool isPublic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initalize the object.
|
|
||||||
*
|
|
||||||
* @param socket socket connection to the server.
|
|
||||||
* @param password password to the server.
|
|
||||||
* @param name name of the stream.
|
|
||||||
* @param url URL associated with the stream.
|
|
||||||
* @param genre genre of the stream.
|
|
||||||
* @param bitRate bitrate of the stream (e.g. mp3 bitrate).
|
|
||||||
* @param isPublic is the stream public?
|
|
||||||
* @param bufferDuration duration of the BufferedSink buffer
|
|
||||||
* in seconds.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( TcpSocket * socket,
|
|
||||||
Sink * streamDump,
|
|
||||||
const char * password,
|
|
||||||
unsigned int bitRate,
|
|
||||||
const char * name,
|
|
||||||
const char * url,
|
|
||||||
const char * genre,
|
|
||||||
bool isPublic,
|
|
||||||
unsigned int bufferDuration )
|
|
||||||
throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-initalize the object.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
strip ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
CastSink ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log in to the server using the socket avialable.
|
|
||||||
*
|
|
||||||
* @return true if login was successful, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
sendLogin ( void ) throw ( Exception ) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the Sink underneath this CastSink.
|
|
||||||
*
|
|
||||||
* @return pointer to the Sink underneath this CastSink.
|
|
||||||
*/
|
|
||||||
inline Sink *
|
|
||||||
getSink ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return bufferedSink.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the TcpSocket underneath this CastSink.
|
|
||||||
*
|
|
||||||
* @return pointer to the TcpSocket underneath this CastSink.
|
|
||||||
*/
|
|
||||||
inline TcpSocket *
|
|
||||||
getSocket ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return socket.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param socket socket connection to the server.
|
|
||||||
* @param password password to the server.
|
|
||||||
* @param name name of the stream.
|
|
||||||
* @param url URL associated with the stream.
|
|
||||||
* @param genre genre of the stream.
|
|
||||||
* @param bitRate bitrate of the stream (e.g. mp3 bitrate).
|
|
||||||
* @param isPublic is the stream public?
|
|
||||||
* @param streamDump a Sink to dump the streamed binary data to
|
|
||||||
* @param bufferDuration duration of the BufferedSink buffer
|
|
||||||
* in seconds.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
CastSink ( TcpSocket * socket,
|
|
||||||
const char * password,
|
|
||||||
unsigned int bitRate,
|
|
||||||
const char * name = 0,
|
|
||||||
const char * url = 0,
|
|
||||||
const char * genre = 0,
|
|
||||||
bool isPublic = false,
|
|
||||||
Sink * streamDump = 0,
|
|
||||||
unsigned int bufferDuration = 10 )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
init( socket,
|
|
||||||
streamDump,
|
|
||||||
password,
|
|
||||||
bitRate,
|
|
||||||
name,
|
|
||||||
url,
|
|
||||||
genre,
|
|
||||||
isPublic,
|
|
||||||
bufferDuration );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor.
|
|
||||||
*
|
|
||||||
* @param cs the CastSink to copy.
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
CastSink( const CastSink & cs ) throw ( Exception )
|
|
||||||
: Sink( cs )
|
|
||||||
{
|
|
||||||
init( cs.socket.get(),
|
|
||||||
cs.streamDump.get(),
|
|
||||||
cs.password,
|
|
||||||
cs.bitRate,
|
|
||||||
cs.name,
|
|
||||||
cs.url,
|
|
||||||
cs.genre,
|
|
||||||
cs.isPublic,
|
|
||||||
cs.bufferDuration );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~CastSink( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param cs the CastSink to assign this to.
|
|
||||||
* @return a reference to this CastSink.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual CastSink &
|
|
||||||
operator= ( const CastSink & cs ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &cs ) {
|
|
||||||
strip();
|
|
||||||
Sink::operator=( cs );
|
|
||||||
init( cs.socket.get(),
|
|
||||||
cs.streamDump.get(),
|
|
||||||
cs.password,
|
|
||||||
cs.bitRate,
|
|
||||||
cs.name,
|
|
||||||
cs.url,
|
|
||||||
cs.genre,
|
|
||||||
cs.isPublic,
|
|
||||||
cs.bufferDuration );
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open the CastSink.
|
|
||||||
* Logs in to the server.
|
|
||||||
*
|
|
||||||
* @return true if opening was successfull, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
open ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the CastSink is open.
|
|
||||||
*
|
|
||||||
* @return true if the CastSink is open, false otherwise.
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isOpen ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return bufferedSink != NULL ? bufferedSink->isOpen() : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the CastSink is ready to accept data.
|
|
||||||
* Blocks until the specified time for data to be available.
|
|
||||||
*
|
|
||||||
* @param sec the maximum seconds to block.
|
|
||||||
* @param usec micro seconds to block after the full seconds.
|
|
||||||
* @return true if the CastSink is ready to accept data,
|
|
||||||
* false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
canWrite ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception )
|
|
||||||
{
|
|
||||||
return getSink()->canWrite( sec, usec);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write data to the CastSink.
|
|
||||||
*
|
|
||||||
* @param buf the data to write.
|
|
||||||
* @param len number of bytes to write from buf.
|
|
||||||
* @return the number of bytes written (may be less than len).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual unsigned int
|
|
||||||
write ( const void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( streamDump != 0 ) {
|
|
||||||
streamDump->write( buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
return getSink()->write( buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush all data that was written to the CastSink to the server.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual void
|
|
||||||
flush ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( streamDump != 0 ) {
|
|
||||||
streamDump->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
return getSink()->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cut what the sink has been doing so far, and start anew.
|
|
||||||
* This usually means separating the data sent to the sink up
|
|
||||||
* until now, and start saving a new chunk of data.
|
|
||||||
*/
|
|
||||||
inline virtual void
|
|
||||||
cut ( void ) throw ()
|
|
||||||
{
|
|
||||||
if ( streamDump != 0 ) {
|
|
||||||
streamDump->cut();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 */
|
|
||||||
|
|
|
@ -1,173 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell ConfigSection
|
|
||||||
|
|
||||||
File : ConfigSection.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <iterator>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
|
|
||||||
#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<const std::string, std::string> element( key, value);
|
|
||||||
std::pair<TableType::iterator, bool> 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());
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,184 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell ConfigSection
|
|
||||||
|
|
||||||
File : ConfigSection.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "Referable.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A configuration file representation. The file is of the syntax:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* # this is a whole line comment
|
|
||||||
* key = value
|
|
||||||
* an ugly key name = long value # this end is a comment too
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* 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<std::string, std::string> 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 */
|
|
||||||
|
|
|
@ -1,358 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : Connector.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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<Sink>[1];
|
|
||||||
sinks[0] = sink;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
unsigned int u;
|
|
||||||
Ref<Sink> * s = new Ref<Sink>[numSinks + 1];
|
|
||||||
|
|
||||||
for ( u = 0; u < numSinks; ++u ) {
|
|
||||||
s[u] = sinks[u].get();
|
|
||||||
}
|
|
||||||
|
|
||||||
s[numSinks] = sink;
|
|
||||||
delete[] sinks;
|
|
||||||
sinks = s;
|
|
||||||
++numSinks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Detach a sink to the connector
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
Connector :: detach ( Sink * sink ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( numSinks == 0 ) {
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
} else if ( numSinks == 1 ) {
|
|
||||||
|
|
||||||
if ( sinks[0].get() != sink ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
sinks[0] = 0;
|
|
||||||
delete[] sinks;
|
|
||||||
sinks = 0;
|
|
||||||
--numSinks;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
unsigned int u;
|
|
||||||
unsigned int v;
|
|
||||||
unsigned int ix;
|
|
||||||
Ref<Sink> * 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<Sink>[numSinks - 1];
|
|
||||||
for ( u = 0, v = 0; u < numSinks; ++u ) {
|
|
||||||
|
|
||||||
if ( u != ix ) {
|
|
||||||
s[v++] = sinks[u];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sinks[ix] = 0;
|
|
||||||
delete[] sinks;
|
|
||||||
sinks = s;
|
|
||||||
--numSinks;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Open the source and all the sinks if needed
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
Connector :: open ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
unsigned int u;
|
|
||||||
|
|
||||||
if ( !source->isOpen() ) {
|
|
||||||
if ( !source->open() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( u = 0; u < numSinks; ++u ) {
|
|
||||||
if ( !sinks[u]->isOpen() ) {
|
|
||||||
if ( !sinks[u]->open() ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if not all could be opened, close those that were
|
|
||||||
if ( u < numSinks ) {
|
|
||||||
unsigned int v;
|
|
||||||
|
|
||||||
for ( v = 0; v < u; ++v ) {
|
|
||||||
sinks[v]->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
source->close();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Transfer some data from the source to the sink
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
Connector :: transfer ( unsigned long bytes,
|
|
||||||
unsigned int bufSize,
|
|
||||||
unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception )
|
|
||||||
{
|
|
||||||
unsigned int u;
|
|
||||||
unsigned long b;
|
|
||||||
|
|
||||||
if ( numSinks == 0 ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( bufSize == 0 ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char * buf = new unsigned char[bufSize];
|
|
||||||
|
|
||||||
reportEvent( 6, "Connector :: tranfer, bytes", bytes);
|
|
||||||
|
|
||||||
for ( b = 0; !bytes || b < bytes; ) {
|
|
||||||
unsigned int d = 0;
|
|
||||||
unsigned int e = 0;
|
|
||||||
|
|
||||||
if ( source->canRead( sec, usec) ) {
|
|
||||||
d = source->read( buf, bufSize);
|
|
||||||
|
|
||||||
// check for EOF
|
|
||||||
if ( d == 0 ) {
|
|
||||||
reportEvent( 3, "Connector :: transfer, EOF");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( u = 0; u < numSinks; ++u ) {
|
|
||||||
|
|
||||||
if ( sinks[u]->canWrite( sec, usec) ) {
|
|
||||||
try {
|
|
||||||
// we expect the sink to accept all data written
|
|
||||||
e = sinks[u]->write( buf, d);
|
|
||||||
} catch ( Exception & e ) {
|
|
||||||
sinks[u]->close();
|
|
||||||
detach( sinks[u].get() );
|
|
||||||
|
|
||||||
reportEvent( 4,
|
|
||||||
"Connector :: transfer, sink removed, remaining",
|
|
||||||
numSinks);
|
|
||||||
|
|
||||||
if ( numSinks == 0 ) {
|
|
||||||
reportEvent( 4,
|
|
||||||
"Connector :: transfer, no more sinks");
|
|
||||||
delete[] buf;
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
// with the call to detach, numSinks gets 1 lower,
|
|
||||||
// and the next sink comes to sinks[u]
|
|
||||||
--u;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
b += d;
|
|
||||||
} else {
|
|
||||||
reportEvent( 3, "Connector :: transfer, can't read");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] buf;
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Signal to each sink to cut what they've done so far, and start anew.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
Connector :: cut ( void ) throw ()
|
|
||||||
{
|
|
||||||
unsigned int u;
|
|
||||||
|
|
||||||
for ( u = 0; u < numSinks; ++u ) {
|
|
||||||
if ( sinks[u]->isOpen() ) {
|
|
||||||
sinks[u]->cut();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,264 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : Connector.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
#ifndef CONNECTOR_H
|
|
||||||
#define CONNECTOR_H
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#error This is a C++ include file
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#include "Referable.h"
|
|
||||||
#include "Ref.h"
|
|
||||||
#include "Reporter.h"
|
|
||||||
#include "Source.h"
|
|
||||||
#include "Sink.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connects a source to one or more sinks.
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class Connector : public virtual Referable, public virtual Reporter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object.
|
|
||||||
*
|
|
||||||
* @param source the source to read from.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( Source * source ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-initialize the object.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
strip ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The source to read from.
|
|
||||||
*/
|
|
||||||
Ref<Source> source;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The sinks to connect the source to.
|
|
||||||
*/
|
|
||||||
Ref<Sink> * sinks;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Total number of sinks.
|
|
||||||
*/
|
|
||||||
unsigned int numSinks;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
Connector ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detach an already attached Sink from the Source of this Connector.
|
|
||||||
*
|
|
||||||
* @param sink the Sink to detach.
|
|
||||||
* @return true if the detachment was successful, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
detach ( Sink * sink ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor based on a Source.
|
|
||||||
*
|
|
||||||
* @param source the source to connect to the sinks.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
Connector ( Source * source ) throw ( Exception )
|
|
||||||
{
|
|
||||||
init( source);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor based on a Source and a Sink.
|
|
||||||
*
|
|
||||||
* @param source the source to connect to the sinks.
|
|
||||||
* @param sink a sink to connect to the source.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
Connector ( Source * source,
|
|
||||||
Sink * sink ) throw ( Exception )
|
|
||||||
{
|
|
||||||
init( source);
|
|
||||||
attach( sink);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor.
|
|
||||||
*
|
|
||||||
* @param connector the object to copy.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
Connector ( const Connector & connector ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~Connector( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param connector the object to assign to this one.
|
|
||||||
* @return a reference to this object.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual Connector &
|
|
||||||
operator= ( const Connector & connector ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of Sinks in the Connector.
|
|
||||||
*
|
|
||||||
* @return the number of Sinks in the Connector.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual unsigned int
|
|
||||||
getNumSinks ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return numSinks;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attach a Sink to the Source of this Connector.
|
|
||||||
*
|
|
||||||
* @param sink the Sink to attach.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
attach ( Sink * sink ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open the connector. Opens the Source and the Sinks if necessary.
|
|
||||||
*
|
|
||||||
* @return true if opening was successful, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
open ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transfer a given amount of data from the Source to all the
|
|
||||||
* Sinks attached.
|
|
||||||
* If an attached Sink closes or encounteres an error during the
|
|
||||||
* process, it is detached and the function carries on with the
|
|
||||||
* rest of the Sinks. If no Sinks remain, or an error is encountered
|
|
||||||
* with the Source, the function returns prematurely.
|
|
||||||
*
|
|
||||||
* @param bytes the amount of data to transfer, in bytes.
|
|
||||||
* If 0, transfer forever.
|
|
||||||
* @param bufSize the size of the buffer to use for transfering.
|
|
||||||
* This amount of data is read from the Source and
|
|
||||||
* written to each Sink on each turn.
|
|
||||||
* @param sec the number of seconds to wait for the Source to have
|
|
||||||
* data available in each turn, and the number of seconds
|
|
||||||
* to wait for the Sinks to accept data.
|
|
||||||
* @param usec the number of micro seconds to wait for the Source to
|
|
||||||
* have data available in each turn, and the number of
|
|
||||||
* micro seconds to wait for the Sinks to accept data.
|
|
||||||
* @return the number of bytes read from the Source.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual unsigned int
|
|
||||||
transfer ( unsigned long bytes,
|
|
||||||
unsigned int bufSize,
|
|
||||||
unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Signal to each sink we have that they need to cut what they are
|
|
||||||
* doing, and start again. For FileSinks, this usually means to
|
|
||||||
* save the archive file recorded so far, and start a new archive
|
|
||||||
* file.
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
cut ( void ) throw ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the Connector. The Source and all Sinks are closed.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
close ( void ) throw ( Exception );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* CONNECTOR_H */
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,319 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : DarkIce.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <unistd.h>
|
|
||||||
#else
|
|
||||||
#error need unistd.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "Referable.h"
|
|
||||||
#include "Reporter.h"
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "Ref.h"
|
|
||||||
#include "AudioSource.h"
|
|
||||||
#include "BufferedSink.h"
|
|
||||||
#include "Connector.h"
|
|
||||||
#include "AudioEncoder.h"
|
|
||||||
#include "TcpSocket.h"
|
|
||||||
#include "CastSink.h"
|
|
||||||
#include "DarkIceConfig.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Program main object.
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class DarkIce : public virtual Referable, public virtual Reporter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of supported outputs. This should be
|
|
||||||
* <supported output types> * <outputs per type>
|
|
||||||
*/
|
|
||||||
static const unsigned int maxOutput = 4 * 7;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type describing each lame library output.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
Ref<AudioEncoder> encoder;
|
|
||||||
Ref<TcpSocket> socket;
|
|
||||||
Ref<CastSink> 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<AudioSource> dsp;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The encoding Connector, connecting the dsp to the encoders.
|
|
||||||
*/
|
|
||||||
Ref<Connector> encConnector;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Should we turn real-time scheduling on ?
|
|
||||||
*/
|
|
||||||
int enableRealTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Original scheduling policy
|
|
||||||
*/
|
|
||||||
int origSchedPolicy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Original scheduling priority
|
|
||||||
*/
|
|
||||||
int origSchedPriority;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object.
|
|
||||||
*
|
|
||||||
* @param config the config Object to read initialization
|
|
||||||
* information from.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( const Config & config ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Look for the icecast stream outputs from the config file.
|
|
||||||
* Called from init()
|
|
||||||
*
|
|
||||||
* @param config the config Object to read initialization
|
|
||||||
* information from.
|
|
||||||
* @param bufferSecs number of seconds to buffer audio for
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
configIceCast ( const Config & config,
|
|
||||||
unsigned int bufferSecs ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Look for the icecast2 stream outputs from the config file.
|
|
||||||
* Called from init()
|
|
||||||
*
|
|
||||||
* @param config the config Object to read initialization
|
|
||||||
* information from.
|
|
||||||
* @param bufferSecs number of seconds to buffer audio for
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
configIceCast2 ( const Config & config,
|
|
||||||
unsigned int bufferSecs ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Look for the shoutcast stream outputs from the config file.
|
|
||||||
* Called from init()
|
|
||||||
*
|
|
||||||
* @param config the config Object to read initialization
|
|
||||||
* information from.
|
|
||||||
* @param bufferSecs number of seconds to buffer audio for
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
configShoutCast ( const Config & config,
|
|
||||||
unsigned int bufferSecs ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Look for file outputs from the config file.
|
|
||||||
* Called from init()
|
|
||||||
*
|
|
||||||
* @param config the config Object to read initialization
|
|
||||||
* information from.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
configFileCast ( const Config & config )
|
|
||||||
throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set POSIX real-time scheduling for the encoding process,
|
|
||||||
* if user permissions enable it.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setRealTimeScheduling ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the scheduling that was before setting real-time scheduling.
|
|
||||||
* This function must be called _only_ after setRealTimeScheduling.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setOriginalScheduling ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start encoding. Spawns all encoders, opens the dsp and
|
|
||||||
* starts sending data to the encoders.
|
|
||||||
*
|
|
||||||
* @return if encoding was successful.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
encode ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start shouting. fork()-s a process for each output, reads
|
|
||||||
* the output of the encoders and sends them to an IceCast server.
|
|
||||||
*
|
|
||||||
* @return if shouting was successful.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
shout ( unsigned int ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
DarkIce ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor based on a configuration object.
|
|
||||||
*
|
|
||||||
* @param config the config Object to read initialization
|
|
||||||
* information from.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
DarkIce ( const Config & config ) throw ( Exception )
|
|
||||||
{
|
|
||||||
init( config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~DarkIce ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO
|
|
||||||
|
|
||||||
inline
|
|
||||||
DarkIce ( const DarkIce & di ) throw ( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline DarkIce &
|
|
||||||
operator= ( const DarkIce * di ) throw ( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the process of recording / encoding / sending to the servers.
|
|
||||||
*
|
|
||||||
* @return 0 on success
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual int
|
|
||||||
run ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Signal to each sink we have that they need to cut what they are
|
|
||||||
* doing, and start again. For FileSinks, this usually means to
|
|
||||||
* save the archive file recorded so far, and start a new archive
|
|
||||||
* file.
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
cut ( void ) throw ();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* DARK_ICE_H */
|
|
||||||
|
|
|
@ -1,166 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell Config
|
|
||||||
|
|
||||||
File : DarkIceConfig.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <iterator>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
|
|
||||||
#include "DarkIceConfig.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Max line size
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
#define LINE_SIZE 256
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* string containing all white space characters
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
#define WHITE_SPACE_STR " \t"
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Get a value for a key
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
const ConfigSection *
|
|
||||||
Config :: get ( const char * key ) const throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !key ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "no key");
|
|
||||||
}
|
|
||||||
|
|
||||||
TableType::const_iterator it = table.find( key);
|
|
||||||
if ( it == table.end() ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return &(it->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Add a configuration line
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
Config :: addLine ( const char * line ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !line ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "no line");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string::size_type ix;
|
|
||||||
std::string str( line);
|
|
||||||
|
|
||||||
/* delete everything after the first # */
|
|
||||||
if ( (ix = str.find( '#')) != str.npos ) {
|
|
||||||
str.erase( ix);
|
|
||||||
}
|
|
||||||
/* eat up all white space from the front */
|
|
||||||
if ( (ix = str.find_first_not_of( WHITE_SPACE_STR)) != str.npos ) {
|
|
||||||
str.erase( 0, ix);
|
|
||||||
}
|
|
||||||
/* eat up all white space from the end */
|
|
||||||
if ( (ix = str.find_last_not_of( WHITE_SPACE_STR)) != str.npos ) {
|
|
||||||
str.erase( ix + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !str.length() ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ( str[0] == '[' && str[str.size()-1] == ']' ) {
|
|
||||||
// a new section starts
|
|
||||||
|
|
||||||
std::string section( str, 1, str.size()-2);
|
|
||||||
ConfigSection cSection;
|
|
||||||
std::pair<const std::string, ConfigSection>
|
|
||||||
element( section, cSection);
|
|
||||||
std::pair<TableType::iterator, bool> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,209 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell Config
|
|
||||||
|
|
||||||
File : DarkIceConfig.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "Referable.h"
|
|
||||||
#include "ConfigSection.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A configuration file representation. The file is of the syntax:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* [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
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* 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<std::string, ConfigSection> TableType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hash table holding the configuration sections.
|
|
||||||
*
|
|
||||||
* @see ConfigSection
|
|
||||||
*/
|
|
||||||
TableType table;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hash table holding the configuration sections.
|
|
||||||
*
|
|
||||||
* @see ConfigSection
|
|
||||||
*/
|
|
||||||
std::string currentSection;
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
Config ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor based on an input stream.
|
|
||||||
*
|
|
||||||
* @param is configuration will be read from this input stream
|
|
||||||
* until end of stream is reached.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
Config ( std::istream & is ) throw ( Exception )
|
|
||||||
{
|
|
||||||
read( is );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~Config ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* TODO
|
|
||||||
|
|
||||||
inline
|
|
||||||
Config ( const Config & di ) throw ( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Config &
|
|
||||||
operator= ( const Config * di ) throw ( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete the configuration information stored in the object.
|
|
||||||
* Resets the object to a clean state.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual void
|
|
||||||
reset ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
table.clear();
|
|
||||||
currentSection = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read a line of confiugration information.
|
|
||||||
*
|
|
||||||
* @param line the line to read.
|
|
||||||
* @return true if the line was correct, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
addLine ( const char * line ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read a line of confiugration information.
|
|
||||||
*
|
|
||||||
* @param is the input stream to read from
|
|
||||||
* @return true if the line was correct, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
read ( std::istream & is ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a ConfigSection by name.
|
|
||||||
*
|
|
||||||
* @param key the name of the ConfigSection
|
|
||||||
* @return the ConfigSection requested, or NULL if it doesn't exists.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual const ConfigSection *
|
|
||||||
get ( const char * key ) const throw ( Exception );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* CONFIG_H */
|
|
||||||
|
|
|
@ -1,201 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : Exception.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <string.h>
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,298 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : Exception.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <iostream>
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An exception class.
|
|
||||||
*
|
|
||||||
* This class should not depend on any other class
|
|
||||||
* should not throw any exceptions itself.
|
|
||||||
*
|
|
||||||
* Typical usage:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* throw Exception( __FILE__, __LINE__, "describe the exception", code);
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @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 */
|
|
||||||
|
|
|
@ -1,191 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : FaacEncoder.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// compile the whole file only if faac support configured in
|
|
||||||
#ifdef HAVE_FAAC_LIB
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "FaacEncoder.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Open an encoding session
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
FaacEncoder :: open ( void )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// open the underlying sink
|
|
||||||
if ( !getSink()->open() ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"faac lib opening underlying sink error");
|
|
||||||
}
|
|
||||||
|
|
||||||
char * faacVersion;
|
|
||||||
char * faacCopyright;
|
|
||||||
faacEncGetVersion(&faacVersion, &faacCopyright);
|
|
||||||
reportEvent(1, "Using faac codec version", faacVersion);
|
|
||||||
|
|
||||||
encoderHandle = faacEncOpen(getInSampleRate(),
|
|
||||||
getInChannel(),
|
|
||||||
&inputSamples,
|
|
||||||
&maxOutputBytes);
|
|
||||||
|
|
||||||
faacEncConfiguration * faacConfig;
|
|
||||||
|
|
||||||
faacConfig = faacEncGetCurrentConfiguration(encoderHandle);
|
|
||||||
|
|
||||||
faacConfig->aacObjectType = MAIN;
|
|
||||||
faacConfig->mpegVersion = MPEG2;
|
|
||||||
faacConfig->useTns = 1;
|
|
||||||
faacConfig->shortctl = SHORTCTL_NORMAL;
|
|
||||||
faacConfig->useLfe = 0;
|
|
||||||
faacConfig->allowMidside = 1;
|
|
||||||
faacConfig->bitRate = getOutBitrate() * 1000 / getOutChannel();
|
|
||||||
faacConfig->bandWidth = lowpass;
|
|
||||||
faacConfig->quantqual = (unsigned long) (getOutQuality() * 1000.0);
|
|
||||||
faacConfig->outputFormat = 1;
|
|
||||||
faacConfig->inputFormat = FAAC_INPUT_16BIT;
|
|
||||||
|
|
||||||
if (!faacEncSetConfiguration(encoderHandle, faacConfig)) {
|
|
||||||
throw Exception(__FILE__, __LINE__,
|
|
||||||
"error configuring faac library");
|
|
||||||
}
|
|
||||||
|
|
||||||
faacOpen = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Write data to the encoder
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
FaacEncoder :: write ( const void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() || len == 0 ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int channels = getInChannel();
|
|
||||||
unsigned int bitsPerSample = getInBitsPerSample();
|
|
||||||
unsigned int sampleSize = (bitsPerSample / 8) * channels;
|
|
||||||
unsigned char * b = (unsigned char*) buf;
|
|
||||||
unsigned int processed = len - (len % sampleSize);
|
|
||||||
unsigned int nSamples = processed / sampleSize;
|
|
||||||
unsigned char * faacBuf = new unsigned char[maxOutputBytes];
|
|
||||||
int samples = (int) nSamples * channels;
|
|
||||||
int processedSamples = 0;
|
|
||||||
|
|
||||||
while (processedSamples < samples) {
|
|
||||||
int outputBytes;
|
|
||||||
int inSamples = samples - processedSamples < (int) inputSamples
|
|
||||||
? samples - processedSamples
|
|
||||||
: inputSamples;
|
|
||||||
|
|
||||||
outputBytes = faacEncEncode(encoderHandle,
|
|
||||||
(int32_t*) (b + processedSamples/sampleSize),
|
|
||||||
inSamples,
|
|
||||||
faacBuf,
|
|
||||||
maxOutputBytes);
|
|
||||||
getSink()->write(faacBuf, outputBytes);
|
|
||||||
|
|
||||||
processedSamples += inSamples;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] faacBuf;
|
|
||||||
|
|
||||||
return processedSamples;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Flush the data from the encoder
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
FaacEncoder :: flush ( void )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
getSink()->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Close the encoding session
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
FaacEncoder :: close ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
flush();
|
|
||||||
faacEncClose(encoderHandle);
|
|
||||||
faacOpen = false;
|
|
||||||
|
|
||||||
getSink()->close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // HAVE_FAAC_LIB
|
|
||||||
|
|
|
@ -1,433 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : FaacEncoder.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
#ifndef AAC_ENCODER_H
|
|
||||||
#define AAC_ENCODER_H
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#error This is a C++ include file
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_FAAC_LIB
|
|
||||||
#include <faac.h>
|
|
||||||
#else
|
|
||||||
#error configure with faac
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "Ref.h"
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "Reporter.h"
|
|
||||||
#include "AudioEncoder.h"
|
|
||||||
#include "Sink.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class representing faac AAC encoder.
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class FaacEncoder : public AudioEncoder, public virtual Reporter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A flag to indicate if the encoding session is open.
|
|
||||||
*/
|
|
||||||
bool faacOpen;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The handle to the AAC encoder instance.
|
|
||||||
*/
|
|
||||||
faacEncHandle encoderHandle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of input samples to supply to the encoder.
|
|
||||||
*/
|
|
||||||
unsigned long inputSamples;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of output bytes the encoder returns in one call.
|
|
||||||
*/
|
|
||||||
unsigned long maxOutputBytes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lowpass filter. Sound frequency in Hz, from where up the
|
|
||||||
* input is cut.
|
|
||||||
*/
|
|
||||||
int lowpass;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object.
|
|
||||||
*
|
|
||||||
* @param lowpass frequency threshold for the lowpass filter.
|
|
||||||
* Input above this frequency is cut.
|
|
||||||
* If 0, faac's default values are used,
|
|
||||||
* which depends on the out sample rate.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline void
|
|
||||||
init ( int lowpass) throw (Exception)
|
|
||||||
{
|
|
||||||
this->faacOpen = false;
|
|
||||||
this->lowpass = lowpass;
|
|
||||||
|
|
||||||
if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 8 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"specified bits per sample not supported",
|
|
||||||
getInBitsPerSample() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( getInChannel() != 1 && getInChannel() != 2 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"unsupported number of input channels for the encoder",
|
|
||||||
getInChannel() );
|
|
||||||
}
|
|
||||||
if ( getOutChannel() != 1 && getOutChannel() != 2 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"unsupported number of output channels for the encoder",
|
|
||||||
getOutChannel() );
|
|
||||||
}
|
|
||||||
if ( getInChannel() != getOutChannel() ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"input channels and output channels do not match");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-initialize the object.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline void
|
|
||||||
strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
FaacEncoder ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param sink the sink to send mp3 output to
|
|
||||||
* @param inSampleRate sample rate of the input.
|
|
||||||
* @param inBitsPerSample number of bits per sample of the input.
|
|
||||||
* @param inChannel number of channels of the input.
|
|
||||||
* @param inBigEndian shows if the input is big or little endian
|
|
||||||
* @param outBitrateMode the bit rate mode of the output.
|
|
||||||
* @param outBitrate bit rate of the output (kbits/sec).
|
|
||||||
* @param outQuality the quality of the stream.
|
|
||||||
* @param outSampleRate sample rate of the output.
|
|
||||||
* If 0, inSampleRate is used.
|
|
||||||
* @param outChannel number of channels of the output.
|
|
||||||
* If 0, inChannel is used.
|
|
||||||
* @param lowpass frequency threshold for the lowpass filter.
|
|
||||||
* Input above this frequency is cut.
|
|
||||||
* If 0, faac's default values are used,
|
|
||||||
* which depends on the out sample rate.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
FaacEncoder ( Sink * sink,
|
|
||||||
unsigned int inSampleRate,
|
|
||||||
unsigned int inBitsPerSample,
|
|
||||||
unsigned int inChannel,
|
|
||||||
bool inBigEndian,
|
|
||||||
BitrateMode outBitrateMode,
|
|
||||||
unsigned int outBitrate,
|
|
||||||
double outQuality,
|
|
||||||
unsigned int outSampleRate = 0,
|
|
||||||
unsigned int outChannel = 0,
|
|
||||||
int lowpass = 0)
|
|
||||||
throw ( Exception )
|
|
||||||
|
|
||||||
: AudioEncoder ( sink,
|
|
||||||
inSampleRate,
|
|
||||||
inBitsPerSample,
|
|
||||||
inChannel,
|
|
||||||
inBigEndian,
|
|
||||||
outBitrateMode,
|
|
||||||
outBitrate,
|
|
||||||
outQuality,
|
|
||||||
outSampleRate,
|
|
||||||
outChannel )
|
|
||||||
{
|
|
||||||
init( lowpass);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param sink the sink to send mp3 output to
|
|
||||||
* @param as get input sample rate, bits per sample and channels
|
|
||||||
* from this AudioSource.
|
|
||||||
* @param outBitrateMode the bit rate mode of the output.
|
|
||||||
* @param outBitrate bit rate of the output (kbits/sec).
|
|
||||||
* @param outQuality the quality of the stream.
|
|
||||||
* @param outSampleRate sample rate of the output.
|
|
||||||
* If 0, input sample rate is used.
|
|
||||||
* @param outChannel number of channels of the output.
|
|
||||||
* If 0, input channel is used.
|
|
||||||
* @param lowpass frequency threshold for the lowpass filter.
|
|
||||||
* Input above this frequency is cut.
|
|
||||||
* If 0, faac's default values are used,
|
|
||||||
* which depends on the out sample rate.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
FaacEncoder ( Sink * sink,
|
|
||||||
const AudioSource * as,
|
|
||||||
BitrateMode outBitrateMode,
|
|
||||||
unsigned int outBitrate,
|
|
||||||
double outQuality,
|
|
||||||
unsigned int outSampleRate = 0,
|
|
||||||
unsigned int outChannel = 0,
|
|
||||||
int lowpass = 0)
|
|
||||||
throw ( Exception )
|
|
||||||
|
|
||||||
: AudioEncoder ( sink,
|
|
||||||
as,
|
|
||||||
outBitrateMode,
|
|
||||||
outBitrate,
|
|
||||||
outQuality,
|
|
||||||
outSampleRate,
|
|
||||||
outChannel )
|
|
||||||
{
|
|
||||||
init( lowpass);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor.
|
|
||||||
*
|
|
||||||
* @param encoder the FaacEncoder to copy.
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
FaacEncoder ( const FaacEncoder & encoder )
|
|
||||||
throw ( Exception )
|
|
||||||
: AudioEncoder( encoder )
|
|
||||||
{
|
|
||||||
init( encoder.lowpass);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~FaacEncoder ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param encoder the FaacEncoder to assign this to.
|
|
||||||
* @return a reference to this FaacEncoder.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual FaacEncoder &
|
|
||||||
operator= ( const FaacEncoder & encoder ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &encoder ) {
|
|
||||||
strip();
|
|
||||||
AudioEncoder::operator=( encoder);
|
|
||||||
init( encoder.lowpass);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the version string of the underlying faac library.
|
|
||||||
*
|
|
||||||
* @return the version string of the underlying faac library.
|
|
||||||
*/
|
|
||||||
inline const char *
|
|
||||||
getFaacVersion( void )
|
|
||||||
{
|
|
||||||
char * id;
|
|
||||||
char * copyright;
|
|
||||||
|
|
||||||
faacEncGetVersion(&id, ©right);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check wether encoding is in progress.
|
|
||||||
*
|
|
||||||
* @return true if encoding is in progress, false otherwise.
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isRunning ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start encoding. This function returns as soon as possible,
|
|
||||||
* with encoding started in the background.
|
|
||||||
*
|
|
||||||
* @return true if encoding has started, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
start ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
return open();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop encoding. Stops the encoding running in the background.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual void
|
|
||||||
stop ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
return close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open an encoding session.
|
|
||||||
*
|
|
||||||
* @return true if opening was successfull, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
open ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the encoding session is open.
|
|
||||||
*
|
|
||||||
* @return true if the encoding session is open, false otherwise.
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isOpen ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return faacOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the encoder is ready to accept data.
|
|
||||||
*
|
|
||||||
* @param sec the maximum seconds to block.
|
|
||||||
* @param usec micro seconds to block after the full seconds.
|
|
||||||
* @return true if the encoder is ready to accept data,
|
|
||||||
* false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
canWrite ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write data to the encoder.
|
|
||||||
* Buf is expected to be a sequence of big-endian 16 bit values,
|
|
||||||
* with left and right channels interleaved. Len is the number of
|
|
||||||
* bytes, must be a multiple of 4.
|
|
||||||
*
|
|
||||||
* @param buf the data to write.
|
|
||||||
* @param len number of bytes to write from buf.
|
|
||||||
* @return the number of bytes written (may be less than len).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual unsigned int
|
|
||||||
write ( const void * buf,
|
|
||||||
unsigned int len ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush all data that was written to the encoder to the underlying
|
|
||||||
* connection.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
flush ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the encoding session.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
close ( void ) throw ( Exception );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* AAC_ENCODER_H */
|
|
||||||
|
|
|
@ -1,89 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : FileCast.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <stdio.h>
|
|
||||||
#else
|
|
||||||
#error need stdio.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,274 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : FileCast.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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<FileSink> 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cut what the sink has been doing so far, and start anew.
|
|
||||||
* This usually means separating the data sent to the sink up
|
|
||||||
* until now, and start saving a new chunk of data.
|
|
||||||
*/
|
|
||||||
inline virtual void
|
|
||||||
cut ( void ) throw ()
|
|
||||||
{
|
|
||||||
targetFile->cut();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the FileCast.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual void
|
|
||||||
close ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
return targetFile->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* FILE_CAST_H */
|
|
||||||
|
|
|
@ -1,382 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : FileSink.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <unistd.h>
|
|
||||||
#else
|
|
||||||
#error need unistd.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STDLIB_H
|
|
||||||
#include <stdlib.h>
|
|
||||||
#else
|
|
||||||
#error need stdlib.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#else
|
|
||||||
#error need sys/types.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_ERRNO_H
|
|
||||||
#include <errno.h>
|
|
||||||
#else
|
|
||||||
#error need errno.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_STAT_H
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#else
|
|
||||||
#error need sys/stat.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_FCNTL_H
|
|
||||||
#include <fcntl.h>
|
|
||||||
#else
|
|
||||||
#error need fcntl.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TIME_H
|
|
||||||
#include <sys/time.h>
|
|
||||||
#else
|
|
||||||
#error need sys/time.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#else
|
|
||||||
#error need string.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SIGNAL_H
|
|
||||||
#include <signal.h>
|
|
||||||
#else
|
|
||||||
#error need signal.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
|
|
||||||
#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 * configName,
|
|
||||||
const char * name ) throw ( Exception )
|
|
||||||
{
|
|
||||||
this->configName = Util::strDup(configName);
|
|
||||||
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.configName, 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.configName, 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 timespec timespec;
|
|
||||||
sigset_t sigset;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO( &fdset);
|
|
||||||
FD_SET( fileDescriptor, &fdset);
|
|
||||||
|
|
||||||
timespec.tv_sec = sec;
|
|
||||||
timespec.tv_nsec = usec * 1000L;
|
|
||||||
|
|
||||||
// mask out SIGUSR1, as we're expecting that signal for other reasons
|
|
||||||
sigemptyset(&sigset);
|
|
||||||
sigaddset(&sigset, SIGUSR1);
|
|
||||||
|
|
||||||
ret = pselect( fileDescriptor + 1, NULL, &fdset, NULL, ×pec, &sigset);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Get the file name to where to move the data saved so far.
|
|
||||||
* The trick is to read the file name from a file named
|
|
||||||
* /tmp/darkice.$configName.$PID , where:
|
|
||||||
* - $configName is the name of the configuration section for this file sink
|
|
||||||
* - $PID is the current process id
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
std::string
|
|
||||||
FileSink :: getArchiveFileName ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
pid_t pid = getpid();
|
|
||||||
std::stringstream metaFileName;
|
|
||||||
|
|
||||||
metaFileName << "/tmp/darkice." << configName << "." << pid;
|
|
||||||
|
|
||||||
std::ifstream ifs(metaFileName.str().c_str());
|
|
||||||
if (!ifs.good()) {
|
|
||||||
throw Exception(__FILE__, __LINE__,
|
|
||||||
"can't find file ", metaFileName.str().c_str(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string archiveFileName;
|
|
||||||
ifs >> archiveFileName;
|
|
||||||
ifs.close();
|
|
||||||
|
|
||||||
return archiveFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Cut what we've done so far, and start anew.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
FileSink :: cut ( void ) throw ()
|
|
||||||
{
|
|
||||||
flush();
|
|
||||||
close();
|
|
||||||
|
|
||||||
try {
|
|
||||||
std::string archiveFileName = getArchiveFileName();
|
|
||||||
|
|
||||||
if (::rename(fileName, archiveFileName.c_str()) != 0) {
|
|
||||||
reportEvent(2, "couldn't move file", fileName,
|
|
||||||
"to", archiveFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch ( Exception &e ) {
|
|
||||||
reportEvent(2, "error during archive cut", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
create();
|
|
||||||
open();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Close the FileSink
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
FileSink :: close ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
flush();
|
|
||||||
::close( fileDescriptor);
|
|
||||||
fileDescriptor = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,278 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : FileSink.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the configuration related to
|
|
||||||
* this file sink. something like "file-0" or "file-2".
|
|
||||||
*/
|
|
||||||
char * configName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Name of the file represented by the FileSink.
|
|
||||||
*/
|
|
||||||
char * fileName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object.
|
|
||||||
*
|
|
||||||
* @param configName the name of the configuration related to
|
|
||||||
* this file sink. something like "file-0" or "file-2".
|
|
||||||
* @param name name of the file to be represented by the object.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( const char * configName,
|
|
||||||
const char * name ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-initialize the object.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
strip ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the file name to where to move the data saved so far.
|
|
||||||
* Used in cut().
|
|
||||||
*
|
|
||||||
* @return the file name where to move the data saved so far.
|
|
||||||
* @throws Exception on file operation errors
|
|
||||||
*/
|
|
||||||
std::string
|
|
||||||
getArchiveFileName( 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 configName the name of the configuration related to
|
|
||||||
* this file sink. something like "file-0" or "file-2".
|
|
||||||
* @param name name of the file to be represented by the object.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
FileSink( const char * configName,
|
|
||||||
const char * name ) throw ( Exception )
|
|
||||||
{
|
|
||||||
init( configName, 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 )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cut what the sink has been doing so far, and start anew.
|
|
||||||
* This usually means separating the data sent to the sink up
|
|
||||||
* until now, and start saving a new chunk of data.
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
cut ( void ) throw ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the FileSink.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
close ( void ) throw ( Exception );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* FILE_SINK_H */
|
|
||||||
|
|
|
@ -1,270 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : FileSource.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 "configure.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#else
|
|
||||||
#error need unistd.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#else
|
|
||||||
#error need sys/types.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_STAT_H
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#else
|
|
||||||
#error need sys/stat.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_FCNTL_H
|
|
||||||
#include <fcntl.h>
|
|
||||||
#else
|
|
||||||
#error need fcntl.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TIME_H
|
|
||||||
#include <sys/time.h>
|
|
||||||
#else
|
|
||||||
#error need sys/time.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#else
|
|
||||||
#error need string.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SIGNAL_H
|
|
||||||
#include <signal.h>
|
|
||||||
#else
|
|
||||||
#error need signal.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "FileSource.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
FileSource :: init ( const char * name ) throw ( Exception )
|
|
||||||
{
|
|
||||||
fileName = Util::strDup( name);
|
|
||||||
fileDescriptor = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* De-initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
FileSource :: strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] fileName;
|
|
||||||
fileDescriptor = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Copy Constructor
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
FileSource :: FileSource ( const FileSource & fs ) throw ( Exception )
|
|
||||||
{
|
|
||||||
init( fs.fileName);
|
|
||||||
|
|
||||||
fileDescriptor = fs.fileDescriptor ? dup( fs.fileDescriptor) : 0;
|
|
||||||
|
|
||||||
if ( fileDescriptor == -1 ) {
|
|
||||||
strip();
|
|
||||||
throw Exception( __FILE__, __LINE__, "dup failure");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Assignment operator
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
FileSource &
|
|
||||||
FileSource :: operator= ( const FileSource & fs ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &fs ) {
|
|
||||||
init( fs.fileName);
|
|
||||||
|
|
||||||
fileDescriptor = fs.fileDescriptor ? dup( fs.fileDescriptor) : 0;
|
|
||||||
|
|
||||||
if ( fileDescriptor == -1 ) {
|
|
||||||
strip();
|
|
||||||
throw Exception( __FILE__, __LINE__, "dup failure");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Check wether a file exists
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
FileSource :: exists ( void ) const throw ()
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if ( stat( (const char*)fileName, &st) == -1 ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Open the source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
FileSource :: open ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (fileDescriptor = ::open( fileName, O_RDONLY)) == -1 ) {
|
|
||||||
fileDescriptor = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Check wether read() would return anything
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
FileSource :: canRead ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception )
|
|
||||||
{
|
|
||||||
fd_set fdset;
|
|
||||||
struct timespec timespec;
|
|
||||||
sigset_t sigset;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO( &fdset);
|
|
||||||
FD_SET( fileDescriptor, &fdset);
|
|
||||||
|
|
||||||
timespec.tv_sec = sec;
|
|
||||||
timespec.tv_nsec = usec * 1000L;
|
|
||||||
|
|
||||||
// mask out SIGUSR1, as we're expecting that signal for other reasons
|
|
||||||
sigemptyset(&sigset);
|
|
||||||
sigaddset(&sigset, SIGUSR1);
|
|
||||||
|
|
||||||
ret = pselect( fileDescriptor + 1, &fdset, NULL, NULL, ×pec, &sigset);
|
|
||||||
|
|
||||||
if ( ret == -1 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "select error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Read from the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
FileSource :: read ( void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ::read( fileDescriptor, buf, len);
|
|
||||||
|
|
||||||
if ( ret == -1 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "read error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Close the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
FileSource :: close ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
::close( fileDescriptor);
|
|
||||||
fileDescriptor = 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,215 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : IceCast.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <stdio.h>
|
|
||||||
#else
|
|
||||||
#error need stdio.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#else
|
|
||||||
#error need string.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_MATH_H
|
|
||||||
#include <math.h>
|
|
||||||
#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 <password> /<mountpoint>\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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,261 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : IceCast.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
#ifndef ICE_CAST_H
|
|
||||||
#define ICE_CAST_H
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#error This is a C++ include file
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#include "Sink.h"
|
|
||||||
#include "TcpSocket.h"
|
|
||||||
#include "CastSink.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class representing output to an IceCast server with
|
|
||||||
* x-audiocast login
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class IceCast : public CastSink
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mount point of the stream on the server.
|
|
||||||
*/
|
|
||||||
char * mountPoint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remote dump file if any.
|
|
||||||
*/
|
|
||||||
char * remoteDumpFile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Description of the stream.
|
|
||||||
*/
|
|
||||||
char * description;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initalize the object.
|
|
||||||
*
|
|
||||||
* @param mountPoint mount point of the stream on the server.
|
|
||||||
* @param remoteDumpFile remote dump file (may be NULL).
|
|
||||||
* @param description description of the stream.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( const char * mountPoint,
|
|
||||||
const char * description,
|
|
||||||
const char * remoteDumpFile )
|
|
||||||
throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-initalize the object.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
strip ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
IceCast ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log in to the server using the socket avialable.
|
|
||||||
*
|
|
||||||
* @return true if login was successful, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
sendLogin ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param socket socket connection to the server.
|
|
||||||
* @param password password to the server.
|
|
||||||
* @param mountPoint mount point of the stream on the server.
|
|
||||||
* @param remoteDumpFile remote dump file (may be NULL).
|
|
||||||
* @param name name of the stream.
|
|
||||||
* @param description description of the stream.
|
|
||||||
* @param url URL associated with the stream.
|
|
||||||
* @param genre genre of the stream.
|
|
||||||
* @param bitRate bitrate of the stream (e.g. mp3 bitrate).
|
|
||||||
* @param isPublic is the stream public?
|
|
||||||
* @param streamDump an optional sink to dump the binary stream
|
|
||||||
* data to.
|
|
||||||
* @param bufferDuration duration of the BufferedSink buffer
|
|
||||||
* in seconds.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
IceCast ( TcpSocket * socket,
|
|
||||||
const char * password,
|
|
||||||
const char * mountPoint,
|
|
||||||
unsigned int bitRate,
|
|
||||||
const char * name = 0,
|
|
||||||
const char * description = 0,
|
|
||||||
const char * url = 0,
|
|
||||||
const char * genre = 0,
|
|
||||||
bool isPublic = false,
|
|
||||||
const char * remoteDumpFile = 0,
|
|
||||||
Sink * streamDump = 0,
|
|
||||||
unsigned int bufferDuration = 10 )
|
|
||||||
throw ( Exception )
|
|
||||||
: CastSink( socket,
|
|
||||||
password,
|
|
||||||
bitRate,
|
|
||||||
name,
|
|
||||||
url,
|
|
||||||
genre,
|
|
||||||
isPublic,
|
|
||||||
streamDump,
|
|
||||||
bufferDuration )
|
|
||||||
{
|
|
||||||
init( mountPoint, description, remoteDumpFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor.
|
|
||||||
*
|
|
||||||
* @param cs the IceCast to copy.
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
IceCast( const IceCast & cs ) throw ( Exception )
|
|
||||||
: CastSink( cs )
|
|
||||||
{
|
|
||||||
init( cs.getMountPoint(),
|
|
||||||
cs.getDescription(),
|
|
||||||
cs.getRemoteDumpFile() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~IceCast( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param cs the IceCast to assign this to.
|
|
||||||
* @return a reference to this IceCast.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual IceCast &
|
|
||||||
operator= ( const IceCast & cs ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &cs ) {
|
|
||||||
strip();
|
|
||||||
CastSink::operator=( cs );
|
|
||||||
init( cs.getMountPoint(),
|
|
||||||
cs.getDescription(),
|
|
||||||
cs.getRemoteDumpFile() );
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the mount point of the stream on the server.
|
|
||||||
*
|
|
||||||
* @return the mount point of the stream on the server.
|
|
||||||
*/
|
|
||||||
inline const char *
|
|
||||||
getMountPoint ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return mountPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the remote dump file if any.
|
|
||||||
*
|
|
||||||
* @return the remote dump file. May be NULL.
|
|
||||||
*/
|
|
||||||
inline const char *
|
|
||||||
getRemoteDumpFile ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return remoteDumpFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the description of the stream.
|
|
||||||
*
|
|
||||||
* @return the description of the stream.
|
|
||||||
*/
|
|
||||||
inline const char *
|
|
||||||
getDescription ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ICE_CAST_H */
|
|
||||||
|
|
|
@ -1,260 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : IceCast2.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <stdio.h>
|
|
||||||
#else
|
|
||||||
#error need stdio.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#else
|
|
||||||
#error need string.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_MATH_H
|
|
||||||
#include <math.h>
|
|
||||||
#else
|
|
||||||
#error need math.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "Source.h"
|
|
||||||
#include "Sink.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "IceCast2.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Size of string conversion buffer
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
#define STRBUF_SIZE 32
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Expected positive response from server begins like this.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char responseOK[] = "HTTP/1.0 200";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
IceCast2 :: init ( StreamFormat format,
|
|
||||||
const char * mountPoint,
|
|
||||||
const char * description )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
this->format = format;
|
|
||||||
this->mountPoint = Util::strDup( mountPoint);
|
|
||||||
this->description = description ? Util::strDup( description) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* De-initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
IceCast2 :: strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
delete[] mountPoint;
|
|
||||||
if ( description ) {
|
|
||||||
delete[] description;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Log in to the IceCast2 server
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
IceCast2 :: sendLogin ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
Sink * sink = getSink();
|
|
||||||
Source * source = getSocket();
|
|
||||||
const char * str;
|
|
||||||
char resp[STRBUF_SIZE];
|
|
||||||
unsigned int len;
|
|
||||||
unsigned int lenExpected;
|
|
||||||
|
|
||||||
if ( !source->isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( !sink->isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// send the request, a string like:
|
|
||||||
// "SOURCE <mountpoint> ICE/1.0"
|
|
||||||
str = "SOURCE /";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
str = getMountPoint();
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
str = " HTTP/1.0";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
|
|
||||||
// send the content type, Ogg Vorbis
|
|
||||||
str = "\nContent-type: ";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
switch ( format ) {
|
|
||||||
case mp3:
|
|
||||||
case mp2:
|
|
||||||
str = "audio/mpeg";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case oggVorbis:
|
|
||||||
str = "application/ogg";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case aac:
|
|
||||||
str = "audio/aac";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case aacp:
|
|
||||||
str = "audio/aacp";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"unsupported stream format", format);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
|
|
||||||
// send the authentication info
|
|
||||||
str = "\nAuthorization: Basic ";
|
|
||||||
sink->write( str, strlen(str));
|
|
||||||
{
|
|
||||||
// send source:<password> encoded as base64
|
|
||||||
char * source = "source:";
|
|
||||||
const char * pwd = getPassword();
|
|
||||||
char * tmp = new char[Util::strLen(source) +
|
|
||||||
Util::strLen(pwd) + 1];
|
|
||||||
Util::strCpy( tmp, source);
|
|
||||||
Util::strCat( tmp, pwd);
|
|
||||||
char * base64 = Util::base64Encode( tmp);
|
|
||||||
delete[] tmp;
|
|
||||||
sink->write( base64, strlen(base64));
|
|
||||||
delete[] base64;
|
|
||||||
}
|
|
||||||
|
|
||||||
// send user agent info
|
|
||||||
str = "\nUser-Agent: DarkIce/" VERSION " (http://darkice.tyrell.hu/)";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
|
|
||||||
// send the ice- headers
|
|
||||||
str = "\nice-bitrate: ";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
if ( log10(getBitRate()) >= (STRBUF_SIZE-2) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"bitrate does not fit string buffer", getBitRate());
|
|
||||||
}
|
|
||||||
sprintf( resp, "%d", getBitRate());
|
|
||||||
sink->write( resp, strlen( resp));
|
|
||||||
|
|
||||||
str = "\nice-public: ";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
str = getIsPublic() ? "1" : "0";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
|
|
||||||
if ( getName() ) {
|
|
||||||
str = "\nice-name: ";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
str = getName();
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( getDescription() ) {
|
|
||||||
str = "\nice-description: ";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
str = getDescription();
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( getUrl() ) {
|
|
||||||
str = "\nice-url: ";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
str = getUrl();
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( getGenre() ) {
|
|
||||||
str = "\nice-genre: ";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
str = getGenre();
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
}
|
|
||||||
|
|
||||||
str = "\n\n";
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
sink->flush();
|
|
||||||
|
|
||||||
// read the response, expected response begins with responseOK
|
|
||||||
lenExpected = Util::strLen( responseOK);
|
|
||||||
if ( (len = source->read( resp, STRBUF_SIZE-1)) < lenExpected ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
resp[lenExpected] = 0;
|
|
||||||
if ( !Util::strEq( resp, responseOK) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// suck anything that the other side has to say
|
|
||||||
while ( source->canRead( 0, 0) &&
|
|
||||||
(len = source->read( resp, STRBUF_SIZE-1)) );
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,269 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : IceCast2.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
#ifndef ICE_CAST2_H
|
|
||||||
#define ICE_CAST2_H
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#error This is a C++ include file
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#include "Sink.h"
|
|
||||||
#include "TcpSocket.h"
|
|
||||||
#include "CastSink.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class representing output to an IceCast2 server with
|
|
||||||
* ice login
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class IceCast2 : public CastSink
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type for specifying the format of the stream.
|
|
||||||
*/
|
|
||||||
enum StreamFormat { mp3, mp2, oggVorbis, aac, aacp };
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The format of the stream.
|
|
||||||
*/
|
|
||||||
StreamFormat format;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mount point of the stream on the server.
|
|
||||||
*/
|
|
||||||
char * mountPoint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Description of the stream.
|
|
||||||
*/
|
|
||||||
char * description;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initalize the object.
|
|
||||||
*
|
|
||||||
* @param mountPoint mount point of the stream on the server.
|
|
||||||
* @param remoteDumpFile remote dump file (may be NULL).
|
|
||||||
* @param description description of the stream.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( StreamFormat format,
|
|
||||||
const char * mountPoint,
|
|
||||||
const char * description )
|
|
||||||
throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-initalize the object.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
strip ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
IceCast2 ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log in to the server using the socket avialable.
|
|
||||||
*
|
|
||||||
* @return true if login was successful, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
sendLogin ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param socket socket connection to the server.
|
|
||||||
* @param password password to the server.
|
|
||||||
* @param mountPoint mount point of the stream on the server.
|
|
||||||
* @param format the format of the stream.
|
|
||||||
* @param name name of the stream.
|
|
||||||
* @param description description of the stream.
|
|
||||||
* @param url URL associated with the stream.
|
|
||||||
* @param genre genre of the stream.
|
|
||||||
* @param bitRate bitrate of the stream (e.g. mp3 bitrate).
|
|
||||||
* @param isPublic is the stream public?
|
|
||||||
* @param streamDump an optional sink to dump the binary stream
|
|
||||||
* data to.
|
|
||||||
* @param bufferDuration duration of the BufferedSink buffer
|
|
||||||
* in seconds.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
IceCast2 ( TcpSocket * socket,
|
|
||||||
const char * password,
|
|
||||||
const char * mountPoint,
|
|
||||||
StreamFormat format,
|
|
||||||
unsigned int bitRate,
|
|
||||||
const char * name = 0,
|
|
||||||
const char * description = 0,
|
|
||||||
const char * url = 0,
|
|
||||||
const char * genre = 0,
|
|
||||||
bool isPublic = false,
|
|
||||||
Sink * streamDump = 0,
|
|
||||||
unsigned int bufferDuration = 10 )
|
|
||||||
throw ( Exception )
|
|
||||||
: CastSink( socket,
|
|
||||||
password,
|
|
||||||
bitRate,
|
|
||||||
name,
|
|
||||||
url,
|
|
||||||
genre,
|
|
||||||
isPublic,
|
|
||||||
streamDump,
|
|
||||||
bufferDuration )
|
|
||||||
{
|
|
||||||
init( format, mountPoint, description);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor.
|
|
||||||
*
|
|
||||||
* @param cs the IceCast2 to copy.
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
IceCast2( const IceCast2 & cs ) throw ( Exception )
|
|
||||||
: CastSink( cs )
|
|
||||||
{
|
|
||||||
init( cs.getFormat(),
|
|
||||||
cs.getMountPoint(),
|
|
||||||
cs.getDescription() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~IceCast2( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param cs the IceCast2 to assign this to.
|
|
||||||
* @return a reference to this IceCast2.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual IceCast2 &
|
|
||||||
operator= ( const IceCast2 & cs ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &cs ) {
|
|
||||||
strip();
|
|
||||||
CastSink::operator=( cs );
|
|
||||||
init( cs.getFormat(),
|
|
||||||
cs.getMountPoint(),
|
|
||||||
cs.getDescription() );
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the format of the stream.
|
|
||||||
*
|
|
||||||
* @return the format of the stream.
|
|
||||||
*/
|
|
||||||
inline StreamFormat
|
|
||||||
getFormat ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return format;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the mount point of the stream on the server.
|
|
||||||
*
|
|
||||||
* @return the mount point of the stream on the server.
|
|
||||||
*/
|
|
||||||
inline const char *
|
|
||||||
getMountPoint ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return mountPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the description of the stream.
|
|
||||||
*
|
|
||||||
* @return the description of the stream.
|
|
||||||
*/
|
|
||||||
inline const char *
|
|
||||||
getDescription ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ICE_CAST2_H */
|
|
||||||
|
|
|
@ -1,470 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Copyright (c) 2005 Nicholas Humfrey. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : JackDspSource.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <limits.h>
|
|
||||||
#include "AudioSource.h"
|
|
||||||
|
|
||||||
#ifdef SUPPORT_JACK_DSP
|
|
||||||
// only compile this code if there is support for it
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#else
|
|
||||||
#error need unistd.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#else
|
|
||||||
#error need string.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#else
|
|
||||||
#error need sys/types.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_MATH_H
|
|
||||||
#include <math.h>
|
|
||||||
#else
|
|
||||||
#error need math.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Util.h"
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "JackDspSource.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
JackDspSource :: init ( const char* name ) throw ( Exception )
|
|
||||||
{
|
|
||||||
// Set defaults
|
|
||||||
ports[0] = NULL; // Left Port
|
|
||||||
ports[1] = NULL; // Right Port
|
|
||||||
rb[0] = NULL; // Left Ring Buffer
|
|
||||||
rb[1] = NULL; // Right Ring Buffer
|
|
||||||
client = NULL;
|
|
||||||
auto_connect = false; // Default is to not auto connect the JACK ports
|
|
||||||
tmp_buffer = NULL; // Buffer big enough for one 'read' of audio
|
|
||||||
|
|
||||||
// Auto connect the ports ?
|
|
||||||
if ( Util::strEq( name, "jack_auto", 9) ) {
|
|
||||||
auto_connect = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the sample size
|
|
||||||
if (getBitsPerSample() != 16) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"JackDspSource doesn't support non 16-bit samples");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* De-initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
JackDspSource :: strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free the temporary buffer
|
|
||||||
if (tmp_buffer) {
|
|
||||||
free(tmp_buffer);
|
|
||||||
tmp_buffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Attempt to connect up the JACK ports automatically
|
|
||||||
* - Just connect left&right to the first two output ports we find
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
JackDspSource :: do_auto_connect ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
const char **all_ports;
|
|
||||||
unsigned int ch = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
Reporter::reportEvent( 10, "JackDspSource :: do_auto_connect");
|
|
||||||
|
|
||||||
// Get a list of all the jack ports
|
|
||||||
all_ports = jack_get_ports (client, NULL, NULL, JackPortIsOutput);
|
|
||||||
if (!ports) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "jack_get_ports() returned NULL.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step through each port name
|
|
||||||
for (i = 0; all_ports[i]; ++i) {
|
|
||||||
|
|
||||||
const char* in = all_ports[i];
|
|
||||||
const char* out = jack_port_name( ports[ch] );
|
|
||||||
|
|
||||||
Reporter::reportEvent( 2, "Connecting", in, "to", out);
|
|
||||||
|
|
||||||
if (jack_connect(client, in, out)) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"Failed to jack_connect() ports", in, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Found enough ports ?
|
|
||||||
if (++ch >= getChannel()) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
free( all_ports );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Open the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
JackDspSource :: open ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
char client_name[255];
|
|
||||||
size_t rb_size;
|
|
||||||
unsigned int c;
|
|
||||||
|
|
||||||
if ( isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register client with Jack
|
|
||||||
if ( jack_client_name != NULL ) {
|
|
||||||
snprintf(client_name, 255, "%s", jack_client_name);
|
|
||||||
} else {
|
|
||||||
snprintf(client_name, 255, "darkice-%d", getpid());
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((client = jack_client_new(client_name)) == NULL) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "JACK server not running?");
|
|
||||||
}
|
|
||||||
Reporter::reportEvent( 1, "Registering as JACK client", client_name);
|
|
||||||
|
|
||||||
|
|
||||||
// Check the sample rate is correct
|
|
||||||
if (jack_get_sample_rate( client ) != (jack_nframes_t)getSampleRate()) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"JACK server sample rate is different than "
|
|
||||||
"sample rate in darkice config file");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Register ports with Jack
|
|
||||||
if (getChannel() == 1) {
|
|
||||||
if (!(ports[0] = jack_port_register(client,
|
|
||||||
"mono",
|
|
||||||
JACK_DEFAULT_AUDIO_TYPE,
|
|
||||||
JackPortIsInput,
|
|
||||||
0))) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"Cannot register input port", "mono");
|
|
||||||
}
|
|
||||||
} else if (getChannel() == 2) {
|
|
||||||
if (!(ports[0] = jack_port_register(client,
|
|
||||||
"left",
|
|
||||||
JACK_DEFAULT_AUDIO_TYPE,
|
|
||||||
JackPortIsInput,
|
|
||||||
0))) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"Cannot register input port", "left");
|
|
||||||
}
|
|
||||||
if (!(ports[1] = jack_port_register(client,
|
|
||||||
"right",
|
|
||||||
JACK_DEFAULT_AUDIO_TYPE,
|
|
||||||
JackPortIsInput, 0))) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"Cannot register input port", "right");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"Invalid number of channels", getChannel());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Create a ring buffer for each channel
|
|
||||||
rb_size = 2
|
|
||||||
* jack_get_sample_rate(client)
|
|
||||||
* sizeof (jack_default_audio_sample_t);
|
|
||||||
for (c=0; c<getChannel(); c++) {
|
|
||||||
rb[c] = jack_ringbuffer_create(rb_size);
|
|
||||||
if (!rb[c]) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"Failed to create ringbuffer for", "channel", c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Set the callbacks
|
|
||||||
jack_on_shutdown(client, JackDspSource::shutdown_callback, (void*)this);
|
|
||||||
if (jack_set_process_callback(client,
|
|
||||||
JackDspSource::process_callback,
|
|
||||||
(void*)this)) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "Failed to set process callback");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Activate client
|
|
||||||
if (jack_activate(client)) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "Can't activate client");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to automatically connect up our input ports to something ?
|
|
||||||
if (auto_connect) {
|
|
||||||
do_auto_connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Check wether read() would return anything
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
JackDspSource :: canRead ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception )
|
|
||||||
{
|
|
||||||
const unsigned int max_wait_time = sec * 1000000;
|
|
||||||
const unsigned int wait_increment = 10000;
|
|
||||||
unsigned int cur_wait = 0;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (max_wait_time > cur_wait) {
|
|
||||||
bool canRead = true;
|
|
||||||
|
|
||||||
for (unsigned int c = 0 ; c < getChannel() ; c++) {
|
|
||||||
if (jack_ringbuffer_read_space(rb[c]) <= 0) {
|
|
||||||
canRead = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (canRead) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_wait += wait_increment;
|
|
||||||
usleep ( wait_increment );
|
|
||||||
}
|
|
||||||
|
|
||||||
usleep( usec );
|
|
||||||
for (unsigned int c = 0 ; c < getChannel() ; c++) {
|
|
||||||
if (jack_ringbuffer_read_space(rb[c]) <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Read from the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
JackDspSource :: read ( void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
jack_nframes_t samples = len / 2 / getChannel();
|
|
||||||
jack_nframes_t samples_read[2] = {0,0};
|
|
||||||
short * output = (short*)buf;
|
|
||||||
unsigned int c, n;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Ensure the temporary buffer is big enough
|
|
||||||
tmp_buffer = (jack_default_audio_sample_t*)realloc(tmp_buffer,
|
|
||||||
samples * sizeof( jack_default_audio_sample_t ) );
|
|
||||||
if (!tmp_buffer) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "realloc on tmp_buffer failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
// We must be sure to fetch as many data on both channels
|
|
||||||
int minBytesAvailable = samples * sizeof( jack_default_audio_sample_t );
|
|
||||||
|
|
||||||
for (c=0; c<getChannel(); c++) {
|
|
||||||
int readable = jack_ringbuffer_read_space(rb[c]);
|
|
||||||
if (readable < minBytesAvailable) {
|
|
||||||
minBytesAvailable = readable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (c=0; c<getChannel(); c++) {
|
|
||||||
// Copy frames from ring buffer to temporary buffer
|
|
||||||
// and then convert samples to output buffer
|
|
||||||
int bytes_read = jack_ringbuffer_read(rb[c],
|
|
||||||
(char*)tmp_buffer,
|
|
||||||
minBytesAvailable);
|
|
||||||
samples_read[c] = bytes_read / sizeof( jack_default_audio_sample_t );
|
|
||||||
|
|
||||||
|
|
||||||
// Convert samples from float to short and put in output buffer
|
|
||||||
for(n=0; n<samples_read[c]; n++) {
|
|
||||||
int tmp = lrintf(tmp_buffer[n] * 32768.0f);
|
|
||||||
if (tmp > SHRT_MAX) {
|
|
||||||
output[n*getChannel()+c] = SHRT_MAX;
|
|
||||||
} else if (tmp < SHRT_MIN) {
|
|
||||||
output[n*getChannel()+c] = SHRT_MIN;
|
|
||||||
} else {
|
|
||||||
output[n*getChannel()+c] = (short) tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Didn't get as many samples as we wanted ?
|
|
||||||
if (getChannel() == 2 && samples_read[0] != samples_read[1]) {
|
|
||||||
Reporter::reportEvent( 2,
|
|
||||||
"Warning: Read a different number of samples "
|
|
||||||
"for left and right channels");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the number of bytes put in the output buffer
|
|
||||||
return samples_read[0] * 2 * getChannel();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Close the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
JackDspSource :: close ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < getChannel(); i++) {
|
|
||||||
// Close the port for channel
|
|
||||||
if ( ports[i] ) {
|
|
||||||
jack_port_unregister( client, ports[i] );
|
|
||||||
ports[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free up the ring buffer for channel
|
|
||||||
if ( rb[i] ) {
|
|
||||||
jack_ringbuffer_free( rb[i] );
|
|
||||||
rb[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Leave the jack graph */
|
|
||||||
if (client) {
|
|
||||||
jack_client_close(client);
|
|
||||||
client = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Callback called by JACK when audio is available
|
|
||||||
*
|
|
||||||
* Don't do anything too expensive here
|
|
||||||
* - just shove audio samples in ring buffer
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
int
|
|
||||||
JackDspSource :: process_callback( jack_nframes_t nframes, void *arg )
|
|
||||||
{
|
|
||||||
JackDspSource* self = (JackDspSource*)arg;
|
|
||||||
size_t to_write = sizeof (jack_default_audio_sample_t) * nframes;
|
|
||||||
unsigned int c;
|
|
||||||
|
|
||||||
// Wait until it is ready
|
|
||||||
if (self->client == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy data to ringbuffer; one per channel */
|
|
||||||
for (c=0; c < self->getChannel(); c++) {
|
|
||||||
char *buf = (char*)jack_port_get_buffer(self->ports[c], nframes);
|
|
||||||
size_t len = jack_ringbuffer_write(self->rb[c], buf, to_write);
|
|
||||||
if (len < to_write) {
|
|
||||||
Reporter::reportEvent( 1, "failed to write to ring ruffer");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Success
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Callback called when
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
JackDspSource :: shutdown_callback( void *arg )
|
|
||||||
{
|
|
||||||
//JackDspSource* self = (JackDspSource*)arg;
|
|
||||||
|
|
||||||
Reporter::reportEvent( 1, "JackDspSource :: shutdown_callback");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // SUPPORT_JACK_DSP
|
|
||||||
|
|
|
@ -1,284 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Copyright (c) 2005 Nicholas Humfrey. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : JackDspSource.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
#ifndef JACK_DSP_SOURCE_H
|
|
||||||
#define JACK_DSP_SOURCE_H
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#error This is a C++ include file
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
|
|
||||||
#include "Reporter.h"
|
|
||||||
#include "AudioSource.h"
|
|
||||||
|
|
||||||
#if defined( HAVE_JACK_LIB )
|
|
||||||
#include <jack/jack.h>
|
|
||||||
#include <jack/ringbuffer.h>
|
|
||||||
#else
|
|
||||||
#error configure for JACK
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An audio input based on JACK
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class JackDspSource : public AudioSource, public virtual Reporter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* The jack client name.
|
|
||||||
*/
|
|
||||||
const char * jack_client_name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The jack port
|
|
||||||
*/
|
|
||||||
jack_port_t * ports[2];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The jack ring buffer.
|
|
||||||
*/
|
|
||||||
jack_ringbuffer_t * rb[2];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The jack client.
|
|
||||||
*/
|
|
||||||
jack_client_t * client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The jack audio sample buffer.
|
|
||||||
*/
|
|
||||||
jack_default_audio_sample_t * tmp_buffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Automatically connect the jack ports ? (default is to not)
|
|
||||||
*/
|
|
||||||
bool auto_connect;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
JackDspSource ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( const char* name ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-initialize the object
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
strip ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempt to connect up the JACK ports automatically
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
do_auto_connect( ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback called by JACK when audio is available
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
process_callback( jack_nframes_t nframes, void *arg );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback called by JACK when jackd is shutting down
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
shutdown_callback( void *arg );
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param name the name of the jack device
|
|
||||||
* @param sampleRate samples per second (e.g. 44100 for 44.1kHz).
|
|
||||||
* @param bitsPerSample bits per sample (e.g. 16 bits).
|
|
||||||
* @param channels number of channels of the audio source
|
|
||||||
* (e.g. 1 for mono, 2 for stereo, etc.).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
JackDspSource ( const char * name,
|
|
||||||
const char * jackClientName,
|
|
||||||
int sampleRate = 44100,
|
|
||||||
int bitsPerSample = 16,
|
|
||||||
int channels = 2 )
|
|
||||||
throw ( Exception )
|
|
||||||
|
|
||||||
: AudioSource( sampleRate, bitsPerSample, channels )
|
|
||||||
{
|
|
||||||
jack_client_name = jackClientName;
|
|
||||||
init( name );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy Constructor.
|
|
||||||
*
|
|
||||||
* @param jds the object to copy.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
JackDspSource ( const JackDspSource & jds ) throw ( Exception )
|
|
||||||
: AudioSource( jds )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__, "JackDspSource doesn't copy");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~JackDspSource ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param ds the object to assign to this one.
|
|
||||||
* @return a reference to this object.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual JackDspSource &
|
|
||||||
operator= ( const JackDspSource & ds ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__, "JackDspSource doesn't assign");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open the JackDspSource.
|
|
||||||
* This does not put the Jack DSP device into recording mode.
|
|
||||||
* To start getting samples, call either canRead() or read().
|
|
||||||
*
|
|
||||||
* @return true if opening was successful, false otherwise
|
|
||||||
* @exception Exception
|
|
||||||
*
|
|
||||||
* @see #canRead
|
|
||||||
* @see #read
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
open ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the JackDspSource is registered
|
|
||||||
*
|
|
||||||
* @return true if Jack client is setup
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isOpen ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return client != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the JackDspSource can be read from.
|
|
||||||
* Blocks until the specified time for data to be available.
|
|
||||||
* Puts the Jack DSP device into recording mode.
|
|
||||||
*
|
|
||||||
* @param sec the maximum seconds to block.
|
|
||||||
* @param usec micro seconds to block after the full seconds.
|
|
||||||
* @return true if the JackDspSource is ready to be read from,
|
|
||||||
* false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
canRead ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read from the JackDspSource.
|
|
||||||
* Puts the Jack DSP device into recording mode.
|
|
||||||
*
|
|
||||||
* @param buf the buffer to read into.
|
|
||||||
* @param len the number of bytes to read into buf
|
|
||||||
* @return the number of bytes read (may be less than len).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual unsigned int
|
|
||||||
read ( void * buf,
|
|
||||||
unsigned int len ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the JackDspSource.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
close ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* JACK_DSP_SOURCE_H */
|
|
||||||
|
|
|
@ -1,396 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : LameLibEncoder.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// compile the whole file only if lame support configured in
|
|
||||||
#ifdef HAVE_LAME_LIB
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "LameLibEncoder.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Open an encoding session
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
LameLibEncoder :: open ( void )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// open the underlying sink
|
|
||||||
if ( !getSink()->open() ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib opening underlying sink error");
|
|
||||||
}
|
|
||||||
|
|
||||||
lameGlobalFlags = lame_init();
|
|
||||||
|
|
||||||
// ugly lame returns -1 in a pointer on allocation errors
|
|
||||||
// this is cast to (long int) so that the pointer can be handled
|
|
||||||
// on 64 bit systems as well
|
|
||||||
if ( !lameGlobalFlags || ((long int)lameGlobalFlags) == -1 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib init error",
|
|
||||||
(long int) lameGlobalFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( 0 > lame_set_num_channels( lameGlobalFlags, getInChannel()) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib setting channels error",
|
|
||||||
getInChannel() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( 0 > lame_set_mode( lameGlobalFlags,
|
|
||||||
getOutChannel() == 1 ? MONO : JOINT_STEREO) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib setting mode error",
|
|
||||||
JOINT_STEREO );
|
|
||||||
}
|
|
||||||
|
|
||||||
reportEvent( 5, "set lame mode", lame_get_mode( lameGlobalFlags));
|
|
||||||
|
|
||||||
reportEvent( 5,
|
|
||||||
"set lame channels",
|
|
||||||
lame_get_num_channels( lameGlobalFlags));
|
|
||||||
|
|
||||||
if ( 0 > lame_set_in_samplerate( lameGlobalFlags, getInSampleRate()) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib setting input sample rate error",
|
|
||||||
getInSampleRate() );
|
|
||||||
}
|
|
||||||
|
|
||||||
reportEvent( 5,
|
|
||||||
"set lame in sample rate",
|
|
||||||
lame_get_in_samplerate( lameGlobalFlags));
|
|
||||||
|
|
||||||
if ( 0 > lame_set_out_samplerate( lameGlobalFlags, getOutSampleRate()) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib setting output sample rate error",
|
|
||||||
getOutSampleRate() );
|
|
||||||
}
|
|
||||||
|
|
||||||
reportEvent( 5,
|
|
||||||
"set lame out sample rate",
|
|
||||||
lame_get_out_samplerate( lameGlobalFlags));
|
|
||||||
|
|
||||||
switch ( getOutBitrateMode() ) {
|
|
||||||
|
|
||||||
case cbr: {
|
|
||||||
|
|
||||||
if ( 0 > lame_set_brate( lameGlobalFlags, getOutBitrate()) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib setting output bit rate error",
|
|
||||||
getOutBitrate() );
|
|
||||||
}
|
|
||||||
|
|
||||||
reportEvent( 5,
|
|
||||||
"set lame bit rate",
|
|
||||||
lame_get_brate( lameGlobalFlags));
|
|
||||||
|
|
||||||
double d = (1.0 - getOutQuality()) * 10.0;
|
|
||||||
|
|
||||||
if ( d > 9 ) {
|
|
||||||
d = 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
int q = int (d);
|
|
||||||
|
|
||||||
if ( 0 > lame_set_quality( lameGlobalFlags, q) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib setting quality error", q);
|
|
||||||
}
|
|
||||||
|
|
||||||
reportEvent( 5,
|
|
||||||
"set lame quality",
|
|
||||||
lame_get_quality( lameGlobalFlags));
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case abr:
|
|
||||||
|
|
||||||
if ( 0 > lame_set_VBR( lameGlobalFlags,vbr_abr)) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib setting abr error", vbr_abr);
|
|
||||||
}
|
|
||||||
|
|
||||||
reportEvent( 5,
|
|
||||||
"set lame abr bitrate",
|
|
||||||
lame_get_VBR( lameGlobalFlags));
|
|
||||||
|
|
||||||
if ( 0 > lame_set_VBR_mean_bitrate_kbps( lameGlobalFlags,
|
|
||||||
getOutBitrate())) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib setting abr mean bitrate error",
|
|
||||||
getOutBitrate());
|
|
||||||
}
|
|
||||||
|
|
||||||
reportEvent( 5,
|
|
||||||
"set lame abr mean bitrate",
|
|
||||||
lame_get_VBR_mean_bitrate_kbps( lameGlobalFlags));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case vbr: {
|
|
||||||
|
|
||||||
if ( 0 > lame_set_VBR( lameGlobalFlags, vbr_mtrh)) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib setting vbr error", vbr_mtrh );
|
|
||||||
}
|
|
||||||
|
|
||||||
reportEvent( 5,
|
|
||||||
"set lame vbr bitrate",
|
|
||||||
lame_get_VBR( lameGlobalFlags));
|
|
||||||
|
|
||||||
double d = (1.0 - getOutQuality()) * 10.0;
|
|
||||||
|
|
||||||
if ( d > 9 ) {
|
|
||||||
d = 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
int q = int (d);
|
|
||||||
|
|
||||||
if ( 0 > lame_set_VBR_q( lameGlobalFlags, q) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib setting vbr quality error", q);
|
|
||||||
}
|
|
||||||
|
|
||||||
reportEvent( 5,
|
|
||||||
"set lame vbr quality",
|
|
||||||
lame_get_VBR_q( lameGlobalFlags));
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ( 0 > lame_set_lowpassfreq( lameGlobalFlags, lowpass) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib setting lowpass frequency error",
|
|
||||||
lowpass );
|
|
||||||
}
|
|
||||||
|
|
||||||
reportEvent( 5,
|
|
||||||
"set lame lowpass frequency",
|
|
||||||
lame_get_lowpassfreq( lameGlobalFlags));
|
|
||||||
|
|
||||||
if ( 0 > lame_set_highpassfreq( lameGlobalFlags, highpass) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib setting highpass frequency error",
|
|
||||||
lowpass );
|
|
||||||
}
|
|
||||||
|
|
||||||
reportEvent( 5,
|
|
||||||
"set lame highpass frequency",
|
|
||||||
lame_get_highpassfreq( lameGlobalFlags));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// not configurable lame settings
|
|
||||||
|
|
||||||
if ( 0 > lame_set_exp_nspsytune( lameGlobalFlags, 1) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib setting psycho acoustic model error");
|
|
||||||
}
|
|
||||||
|
|
||||||
reportEvent( 5,
|
|
||||||
"set lame psycho acoustic model",
|
|
||||||
lame_get_exp_nspsytune( lameGlobalFlags));
|
|
||||||
|
|
||||||
if ( 0 > lame_set_error_protection( lameGlobalFlags, 1) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib setting error protection error",
|
|
||||||
1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
reportEvent( 5,
|
|
||||||
"set lame error protection",
|
|
||||||
lame_get_error_protection( lameGlobalFlags));
|
|
||||||
|
|
||||||
// let lame init its own params based on our settings
|
|
||||||
if ( 0 > lame_init_params( lameGlobalFlags) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"lame lib initializing params error" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getReportVerbosity() >= 3) {
|
|
||||||
lame_print_config( lameGlobalFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Write data to the encoder
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
LameLibEncoder :: write ( const void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() || len == 0 ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int bitsPerSample = getInBitsPerSample();
|
|
||||||
unsigned int inChannels = getInChannel();
|
|
||||||
|
|
||||||
unsigned int sampleSize = (bitsPerSample / 8) * inChannels;
|
|
||||||
unsigned char * b = (unsigned char*) buf;
|
|
||||||
unsigned int processed = len - (len % sampleSize);
|
|
||||||
unsigned int nSamples = processed / sampleSize;
|
|
||||||
short int * leftBuffer = new short int[nSamples];
|
|
||||||
short int * rightBuffer = new short int[nSamples];
|
|
||||||
|
|
||||||
if ( bitsPerSample == 8 ) {
|
|
||||||
Util::conv8( b, processed, leftBuffer, rightBuffer, inChannels);
|
|
||||||
} else if ( bitsPerSample == 16 ) {
|
|
||||||
Util::conv16( b,
|
|
||||||
processed,
|
|
||||||
leftBuffer,
|
|
||||||
rightBuffer,
|
|
||||||
inChannels,
|
|
||||||
isInBigEndian());
|
|
||||||
} else {
|
|
||||||
delete[] leftBuffer;
|
|
||||||
delete[] rightBuffer;
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"unsupported number of bits per sample for the encoder",
|
|
||||||
bitsPerSample );
|
|
||||||
}
|
|
||||||
|
|
||||||
// data chunk size estimate according to lame documentation
|
|
||||||
// NOTE: mp3Size is calculated based on the number of input channels
|
|
||||||
// which may be bigger than need, as output channels can be less
|
|
||||||
unsigned int mp3Size = (unsigned int) (1.25 * nSamples + 7200);
|
|
||||||
unsigned char * mp3Buf = new unsigned char[mp3Size];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = lame_encode_buffer( lameGlobalFlags,
|
|
||||||
leftBuffer,
|
|
||||||
inChannels == 2 ? rightBuffer : leftBuffer,
|
|
||||||
nSamples,
|
|
||||||
mp3Buf,
|
|
||||||
mp3Size );
|
|
||||||
|
|
||||||
delete[] leftBuffer;
|
|
||||||
delete[] rightBuffer;
|
|
||||||
|
|
||||||
if ( ret < 0 ) {
|
|
||||||
reportEvent( 3, "lame encoding error", ret);
|
|
||||||
delete[] mp3Buf;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int written = getSink()->write( mp3Buf, ret);
|
|
||||||
delete[] mp3Buf;
|
|
||||||
// just let go data that could not be written
|
|
||||||
if ( written < (unsigned int) ret ) {
|
|
||||||
reportEvent( 2,
|
|
||||||
"couldn't write all from encoder to underlying sink",
|
|
||||||
ret - written);
|
|
||||||
}
|
|
||||||
|
|
||||||
return processed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Flush the data from the encoder
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
LameLibEncoder :: flush ( void )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// data chunk size estimate according to lame documentation
|
|
||||||
unsigned int mp3Size = 7200;
|
|
||||||
unsigned char * mp3Buf = new unsigned char[mp3Size];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = lame_encode_flush( lameGlobalFlags, mp3Buf, mp3Size );
|
|
||||||
|
|
||||||
unsigned int written = getSink()->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);
|
|
||||||
}
|
|
||||||
|
|
||||||
getSink()->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Close the encoding session
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
LameLibEncoder :: close ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
flush();
|
|
||||||
lame_close( lameGlobalFlags);
|
|
||||||
lameGlobalFlags = 0;
|
|
||||||
|
|
||||||
getSink()->close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // HAVE_LAME_LIB
|
|
||||||
|
|
|
@ -1,438 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : LameLibEncoder.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <lame/lame.h>
|
|
||||||
#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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 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 ( int lowpass,
|
|
||||||
int highpass ) throw ( Exception )
|
|
||||||
{
|
|
||||||
this->lameGlobalFlags = NULL;
|
|
||||||
this->lowpass = lowpass;
|
|
||||||
this->highpass = highpass;
|
|
||||||
|
|
||||||
if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 8 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"specified bits per sample not supported",
|
|
||||||
getInBitsPerSample() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( getInChannel() != 1 && getInChannel() != 2 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"unsupported number of input channels for the encoder",
|
|
||||||
getInChannel() );
|
|
||||||
}
|
|
||||||
if ( getOutChannel() != 1 && getOutChannel() != 2 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"unsupported number of output channels for the encoder",
|
|
||||||
getOutChannel() );
|
|
||||||
}
|
|
||||||
if ( getInChannel() < getOutChannel() ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"output channels greater then input channels",
|
|
||||||
getOutChannel() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-initialize the object.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline void
|
|
||||||
strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
LameLibEncoder ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param sink the sink to send mp3 output to
|
|
||||||
* @param inSampleRate sample rate of the input.
|
|
||||||
* @param inBitsPerSample number of bits per sample of the input.
|
|
||||||
* @param inChannel number of channels of the input.
|
|
||||||
* @param inBigEndian shows if the input is big or little endian
|
|
||||||
* @param outBitrateMode the bit rate mode of the output.
|
|
||||||
* @param outBitrate bit rate of the output (kbits/sec).
|
|
||||||
* @param outQuality the quality of the stream.
|
|
||||||
* @param outSampleRate sample rate of the output.
|
|
||||||
* If 0, inSampleRate is used.
|
|
||||||
* @param outChannel number of channels of the output.
|
|
||||||
* If 0, inChannel is used.
|
|
||||||
* @param lowpass frequency threshold for the lowpass filter.
|
|
||||||
* Input above this frequency is cut.
|
|
||||||
* If 0, lame's default values are used,
|
|
||||||
* which depends on the out sample rate.
|
|
||||||
* @param highpass frequency threshold for the highpass filter.
|
|
||||||
* Input below this frequency is cut.
|
|
||||||
* If 0, lame's default values are used,
|
|
||||||
* which depends on the out sample rate.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
LameLibEncoder ( Sink * sink,
|
|
||||||
unsigned int inSampleRate,
|
|
||||||
unsigned int inBitsPerSample,
|
|
||||||
unsigned int inChannel,
|
|
||||||
bool inBigEndian,
|
|
||||||
BitrateMode outBitrateMode,
|
|
||||||
unsigned int outBitrate,
|
|
||||||
double outQuality,
|
|
||||||
unsigned int outSampleRate = 0,
|
|
||||||
unsigned int outChannel = 0,
|
|
||||||
int lowpass = 0,
|
|
||||||
int highpass = 0 )
|
|
||||||
throw ( Exception )
|
|
||||||
|
|
||||||
: AudioEncoder ( sink,
|
|
||||||
inSampleRate,
|
|
||||||
inBitsPerSample,
|
|
||||||
inChannel,
|
|
||||||
inBigEndian,
|
|
||||||
outBitrateMode,
|
|
||||||
outBitrate,
|
|
||||||
outQuality,
|
|
||||||
outSampleRate,
|
|
||||||
outChannel )
|
|
||||||
{
|
|
||||||
init( 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 ( sink,
|
|
||||||
as,
|
|
||||||
outBitrateMode,
|
|
||||||
outBitrate,
|
|
||||||
outQuality,
|
|
||||||
outSampleRate,
|
|
||||||
outChannel )
|
|
||||||
{
|
|
||||||
init( lowpass, highpass);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor.
|
|
||||||
*
|
|
||||||
* @param encoder the LameLibEncoder to copy.
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
LameLibEncoder ( const LameLibEncoder & encoder )
|
|
||||||
throw ( Exception )
|
|
||||||
: AudioEncoder( encoder )
|
|
||||||
{
|
|
||||||
init( 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.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 */
|
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
bin_PROGRAMS = darkice
|
|
||||||
AM_CXXFLAGS = -O2 -pedantic -Wall @DEBUG_CXXFLAGS@ @PTHREAD_CFLAGS@
|
|
||||||
@JACK_CFLAGS@
|
|
||||||
INCLUDES = @LAME_INCFLAGS@ @VORBIS_INCFLAGS@ @FAAC_INCFLAGS@ @AACPLUS_INCFLAGS@ @TWOLAME_INCFLAGS@ @ALSA_INCFLAGS@
|
|
||||||
LDADD = @PTHREAD_LIBS@ @LAME_LDFLAGS@ @VORBIS_LDFLAGS@ @FAAC_LDFLAGS@ @AACPLUS_LDFLAGS@ @TWOLAME_LDFLAGS@ \
|
|
||||||
@ALSA_LDFLAGS@ @JACK_LDFLAGS@
|
|
||||||
|
|
||||||
darkice_SOURCES = AudioEncoder.h\
|
|
||||||
AudioSource.h\
|
|
||||||
AudioSource.cpp\
|
|
||||||
BufferedSink.cpp\
|
|
||||||
BufferedSink.h\
|
|
||||||
CastSink.cpp\
|
|
||||||
CastSink.h\
|
|
||||||
FileSink.h\
|
|
||||||
FileSink.cpp\
|
|
||||||
Connector.cpp\
|
|
||||||
Connector.h\
|
|
||||||
MultiThreadedConnector.cpp\
|
|
||||||
MultiThreadedConnector.h\
|
|
||||||
DarkIce.cpp\
|
|
||||||
DarkIce.h\
|
|
||||||
Exception.cpp\
|
|
||||||
Exception.h\
|
|
||||||
IceCast.cpp\
|
|
||||||
IceCast.h\
|
|
||||||
IceCast2.cpp\
|
|
||||||
IceCast2.h\
|
|
||||||
ShoutCast.cpp\
|
|
||||||
ShoutCast.h\
|
|
||||||
FileCast.h\
|
|
||||||
FileCast.cpp\
|
|
||||||
LameLibEncoder.cpp\
|
|
||||||
LameLibEncoder.h\
|
|
||||||
TwoLameLibEncoder.cpp\
|
|
||||||
TwoLameLibEncoder.h\
|
|
||||||
VorbisLibEncoder.cpp\
|
|
||||||
VorbisLibEncoder.h\
|
|
||||||
FaacEncoder.cpp\
|
|
||||||
FaacEncoder.h\
|
|
||||||
aacPlusEncoder.cpp\
|
|
||||||
aacPlusEncoder.h\
|
|
||||||
aflibDebug.h\
|
|
||||||
aflibDebug.cc\
|
|
||||||
aflibConverter.h\
|
|
||||||
aflibConverter.cc\
|
|
||||||
aflibConverterLargeFilter.h\
|
|
||||||
aflibConverterSmallFilter.h\
|
|
||||||
OssDspSource.cpp\
|
|
||||||
OssDspSource.h\
|
|
||||||
SerialUlaw.cpp\
|
|
||||||
SerialUlaw.h\
|
|
||||||
SolarisDspSource.cpp\
|
|
||||||
SolarisDspSource.h\
|
|
||||||
Ref.h\
|
|
||||||
Referable.h\
|
|
||||||
Sink.h\
|
|
||||||
Source.h\
|
|
||||||
TcpSocket.cpp\
|
|
||||||
TcpSocket.h\
|
|
||||||
Util.cpp\
|
|
||||||
Util.h\
|
|
||||||
ConfigSection.h\
|
|
||||||
ConfigSection.cpp\
|
|
||||||
DarkIceConfig.h\
|
|
||||||
DarkIceConfig.cpp\
|
|
||||||
Reporter.h\
|
|
||||||
Reporter.cpp\
|
|
||||||
AlsaDspSource.h\
|
|
||||||
AlsaDspSource.cpp\
|
|
||||||
JackDspSource.h\
|
|
||||||
JackDspSource.cpp\
|
|
||||||
main.cpp
|
|
||||||
|
|
|
@ -1,429 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : MultiThreadedConnector.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#else
|
|
||||||
#error need sys/types.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "MultiThreadedConnector.h"
|
|
||||||
#include "Util.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
MultiThreadedConnector :: init ( bool reconnect ) throw ( Exception )
|
|
||||||
{
|
|
||||||
this->reconnect = reconnect;
|
|
||||||
|
|
||||||
pthread_mutex_init( &mutexProduce, 0);
|
|
||||||
pthread_cond_init( &condProduce, 0);
|
|
||||||
threads = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* De-initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
MultiThreadedConnector :: strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( threads ) {
|
|
||||||
delete[] threads;
|
|
||||||
threads = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_cond_destroy( &condProduce);
|
|
||||||
pthread_mutex_destroy( &mutexProduce);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Constructor
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
MultiThreadedConnector :: MultiThreadedConnector (
|
|
||||||
const MultiThreadedConnector & connector )
|
|
||||||
throw ( Exception )
|
|
||||||
: Connector( connector)
|
|
||||||
{
|
|
||||||
reconnect = connector.reconnect;
|
|
||||||
mutexProduce = connector.mutexProduce;
|
|
||||||
condProduce = connector.condProduce;
|
|
||||||
|
|
||||||
if ( threads ) {
|
|
||||||
delete[] threads;
|
|
||||||
}
|
|
||||||
threads = new ThreadData[numSinks];
|
|
||||||
for ( unsigned int i = 0; i < numSinks; ++i ) {
|
|
||||||
threads[i] = connector.threads[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Assignment operator
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
MultiThreadedConnector &
|
|
||||||
MultiThreadedConnector :: operator= ( const MultiThreadedConnector & connector )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &connector ) {
|
|
||||||
Connector::operator=( connector);
|
|
||||||
|
|
||||||
reconnect = connector.reconnect;
|
|
||||||
mutexProduce = connector.mutexProduce;
|
|
||||||
condProduce = connector.condProduce;
|
|
||||||
|
|
||||||
if ( threads ) {
|
|
||||||
delete[] threads;
|
|
||||||
}
|
|
||||||
threads = new ThreadData[numSinks];
|
|
||||||
for ( unsigned int i = 0; i < numSinks; ++i ) {
|
|
||||||
threads[i] = connector.threads[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Open the source and all the sinks if needed
|
|
||||||
* Create the sink threads
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
MultiThreadedConnector :: open ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
size_t st;
|
|
||||||
|
|
||||||
if ( !Connector::open() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
running = true;
|
|
||||||
|
|
||||||
pthread_attr_init( &threadAttr);
|
|
||||||
pthread_attr_getstacksize(&threadAttr, &st);
|
|
||||||
if (st < 128 * 1024) {
|
|
||||||
reportEvent( 5, "MultiThreadedConnector :: open, stack size ",
|
|
||||||
(long)st);
|
|
||||||
st = 128 * 1024;
|
|
||||||
pthread_attr_setstacksize(&threadAttr, st);
|
|
||||||
}
|
|
||||||
pthread_attr_setdetachstate( &threadAttr, PTHREAD_CREATE_JOINABLE);
|
|
||||||
|
|
||||||
threads = new ThreadData[numSinks];
|
|
||||||
for ( i = 0; i < numSinks; ++i ) {
|
|
||||||
ThreadData * threadData = threads + i;
|
|
||||||
|
|
||||||
threadData->connector = this;
|
|
||||||
threadData->ixSink = i;
|
|
||||||
threadData->accepting = true;
|
|
||||||
threadData->isDone = true;
|
|
||||||
if ( pthread_create( &(threadData->thread),
|
|
||||||
&threadAttr,
|
|
||||||
ThreadData::threadFunction,
|
|
||||||
threadData ) ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if could not create all, delete the ones created
|
|
||||||
if ( i < numSinks ) {
|
|
||||||
unsigned int j;
|
|
||||||
|
|
||||||
// signal to stop for all running threads
|
|
||||||
pthread_mutex_lock( &mutexProduce);
|
|
||||||
running = false;
|
|
||||||
pthread_cond_broadcast( &condProduce);
|
|
||||||
pthread_mutex_unlock( &mutexProduce);
|
|
||||||
|
|
||||||
for ( j = 0; j < i; ++j ) {
|
|
||||||
pthread_join( threads[j].thread, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] threads;
|
|
||||||
threads = 0;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Transfer some data from the source to the sink
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
MultiThreadedConnector :: transfer ( unsigned long bytes,
|
|
||||||
unsigned int bufSize,
|
|
||||||
unsigned int sec,
|
|
||||||
unsigned int usec )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
unsigned int b;
|
|
||||||
|
|
||||||
if ( numSinks == 0 ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( bufSize == 0 ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dataBuffer = new unsigned char[bufSize];
|
|
||||||
dataSize = 0;
|
|
||||||
|
|
||||||
reportEvent( 6, "MultiThreadedConnector :: tranfer, bytes", bytes);
|
|
||||||
|
|
||||||
for ( b = 0; !bytes || b < bytes; ) {
|
|
||||||
if ( source->canRead( sec, usec) ) {
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
pthread_mutex_lock( &mutexProduce);
|
|
||||||
dataSize = source->read( dataBuffer, bufSize);
|
|
||||||
b += dataSize;
|
|
||||||
|
|
||||||
// check for EOF
|
|
||||||
if ( dataSize == 0 ) {
|
|
||||||
reportEvent( 3, "MultiThreadedConnector :: transfer, EOF");
|
|
||||||
pthread_mutex_unlock( &mutexProduce);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = 0; i < numSinks; ++i ) {
|
|
||||||
threads[i].isDone = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// tell sink threads that there is some data available
|
|
||||||
pthread_cond_broadcast( &condProduce);
|
|
||||||
|
|
||||||
// wait for all sink threads to get done with this data
|
|
||||||
while ( true ) {
|
|
||||||
for ( i = 0; i < numSinks && threads[i].isDone; ++i );
|
|
||||||
if ( i == numSinks ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pthread_cond_wait( &condProduce, &mutexProduce);
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock( &mutexProduce);
|
|
||||||
} else {
|
|
||||||
reportEvent( 3, "MultiThreadedConnector :: transfer, can't read");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] dataBuffer;
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* The function for each thread.
|
|
||||||
* Read the presented data
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
MultiThreadedConnector :: sinkThread( int ixSink )
|
|
||||||
{
|
|
||||||
ThreadData * threadData = &threads[ixSink];
|
|
||||||
Sink * sink = sinks[ixSink].get();
|
|
||||||
|
|
||||||
while ( running ) {
|
|
||||||
// wait for some data to become available
|
|
||||||
pthread_mutex_lock( &mutexProduce);
|
|
||||||
while ( running && threadData->isDone ) {
|
|
||||||
pthread_cond_wait( &condProduce, &mutexProduce);
|
|
||||||
}
|
|
||||||
if ( !running ) {
|
|
||||||
pthread_mutex_unlock( &mutexProduce);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( threadData->cut) {
|
|
||||||
sink->cut();
|
|
||||||
threadData->cut = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( threadData->accepting ) {
|
|
||||||
if ( sink->canWrite( 0, 0) ) {
|
|
||||||
try {
|
|
||||||
sink->write( dataBuffer, dataSize);
|
|
||||||
} catch ( Exception & e ) {
|
|
||||||
// something wrong. don't accept more data, try to
|
|
||||||
// reopen the sink next time around
|
|
||||||
threadData->accepting = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
reportEvent( 4,
|
|
||||||
"MultiThreadedConnector :: sinkThread can't write ",
|
|
||||||
ixSink);
|
|
||||||
// don't care if we can't write
|
|
||||||
}
|
|
||||||
}
|
|
||||||
threadData->isDone = true;
|
|
||||||
pthread_cond_broadcast( &condProduce);
|
|
||||||
pthread_mutex_unlock( &mutexProduce);
|
|
||||||
|
|
||||||
if ( !threadData->accepting ) {
|
|
||||||
if ( reconnect ) {
|
|
||||||
reportEvent( 4,
|
|
||||||
"MultiThreadedConnector :: sinkThread reconnecting ",
|
|
||||||
ixSink);
|
|
||||||
// if we're not accepting, try to reopen the sink
|
|
||||||
try {
|
|
||||||
sink->close();
|
|
||||||
Util::sleep(1L, 0L);
|
|
||||||
sink->open();
|
|
||||||
sched_yield();
|
|
||||||
threadData->accepting = sink->isOpen();
|
|
||||||
} catch ( Exception & e ) {
|
|
||||||
// don't care, just try and try again
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// if !reconnect, just stop the connector
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Signal to each sink to cut what they've done so far, and start anew.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
MultiThreadedConnector :: cut ( void ) throw ()
|
|
||||||
{
|
|
||||||
for ( unsigned int i = 0; i < numSinks; ++i ) {
|
|
||||||
threads[i].cut = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: it might be more appropriate to signal all the threads here
|
|
||||||
// but, they'll get signaled on new data anyway, and it might be
|
|
||||||
// enough for them to cut at that time
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Stop the treads
|
|
||||||
* Close the source and all the sinks if needed
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
MultiThreadedConnector :: close ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
// signal to stop for all threads
|
|
||||||
pthread_mutex_lock( &mutexProduce);
|
|
||||||
running = false;
|
|
||||||
pthread_cond_broadcast( &condProduce);
|
|
||||||
pthread_mutex_unlock( &mutexProduce);
|
|
||||||
|
|
||||||
// wait for all the threads to finish
|
|
||||||
for ( i = 0; i < numSinks; ++i ) {
|
|
||||||
pthread_join( threads[i].thread, 0);
|
|
||||||
}
|
|
||||||
pthread_attr_destroy( &threadAttr);
|
|
||||||
|
|
||||||
Connector::close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* The thread function
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void *
|
|
||||||
MultiThreadedConnector :: ThreadData :: threadFunction( void * param )
|
|
||||||
{
|
|
||||||
struct sched_param sched;
|
|
||||||
int sched_type;
|
|
||||||
ThreadData * threadData = (ThreadData*) param;
|
|
||||||
|
|
||||||
pthread_getschedparam( threadData->thread, &sched_type, &sched );
|
|
||||||
|
|
||||||
reportEvent( 5,
|
|
||||||
"MultiThreadedConnector :: ThreadData :: threadFunction, "
|
|
||||||
"was (thread, priority, type): ",
|
|
||||||
param,
|
|
||||||
sched.sched_priority,
|
|
||||||
sched_type == SCHED_FIFO ? "SCHED_FIFO" :
|
|
||||||
sched_type == SCHED_RR ? "SCHED_RR" :
|
|
||||||
sched_type == SCHED_OTHER ? "SCHED_OTHER" :
|
|
||||||
"INVALID"
|
|
||||||
);
|
|
||||||
|
|
||||||
sched.sched_priority = 1;
|
|
||||||
pthread_setschedparam( threadData->thread, SCHED_FIFO, &sched);
|
|
||||||
|
|
||||||
pthread_getschedparam( threadData->thread, &sched_type, &sched );
|
|
||||||
reportEvent( 5,
|
|
||||||
"MultiThreadedConnector :: ThreadData :: threadFunction, "
|
|
||||||
"now is (thread, priority, type): ",
|
|
||||||
param,
|
|
||||||
sched.sched_priority,
|
|
||||||
sched_type == SCHED_FIFO ? "SCHED_FIFO" :
|
|
||||||
sched_type == SCHED_RR ? "SCHED_RR" :
|
|
||||||
sched_type == SCHED_OTHER ? "SCHED_OTHER" :
|
|
||||||
"INVALID"
|
|
||||||
);
|
|
||||||
|
|
||||||
threadData->connector->sinkThread( threadData->ixSink);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,359 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : MultiThreadedConnector.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
#ifndef MULTI_THREADED_CONNECTOR_H
|
|
||||||
#define MULTI_THREADED_CONNECTOR_H
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#error This is a C++ include file
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// check for __NetBSD__ because it won't be found by AC_CHECK_HEADER on NetBSD
|
|
||||||
// as pthread.h is in /usr/pkg/include, not /usr/include
|
|
||||||
#if defined( HAVE_PTHREAD_H ) || defined( __NetBSD__ )
|
|
||||||
#include <pthread.h>
|
|
||||||
#else
|
|
||||||
#error need pthread.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Referable.h"
|
|
||||||
#include "Ref.h"
|
|
||||||
#include "Reporter.h"
|
|
||||||
#include "Source.h"
|
|
||||||
#include "Sink.h"
|
|
||||||
#include "Connector.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Connects a source to one or more sinks, using a multi-threaded
|
|
||||||
* producer - consumer approach.
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class MultiThreadedConnector : public virtual Connector
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper class to collect information for starting threads.
|
|
||||||
*/
|
|
||||||
class ThreadData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* The connector starting the thread
|
|
||||||
*/
|
|
||||||
MultiThreadedConnector * connector;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The index of the sink this thread writes to.
|
|
||||||
*/
|
|
||||||
unsigned int ixSink;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The POSIX thread itself.
|
|
||||||
*/
|
|
||||||
pthread_t thread;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Marks if the thread is accepting data.
|
|
||||||
*/
|
|
||||||
bool accepting;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Marks if the thread has processed the last batch
|
|
||||||
* of data.
|
|
||||||
*/
|
|
||||||
bool isDone;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A flag to show that the sink should be made to cut in the
|
|
||||||
* next iteration.
|
|
||||||
*/
|
|
||||||
bool cut;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor.
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
ThreadData()
|
|
||||||
{
|
|
||||||
this->connector = 0;
|
|
||||||
this->ixSink = 0;
|
|
||||||
this->thread = 0;
|
|
||||||
this->accepting = false;
|
|
||||||
this->isDone = false;
|
|
||||||
this->cut = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The thread function.
|
|
||||||
*
|
|
||||||
* @param param thread parameter, a pointer to a
|
|
||||||
* ThreadData
|
|
||||||
* @return nothing
|
|
||||||
*/
|
|
||||||
static void *
|
|
||||||
threadFunction( void * param );
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The mutex of this object.
|
|
||||||
*/
|
|
||||||
pthread_mutex_t mutexProduce;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The conditional variable for presenting new data.
|
|
||||||
*/
|
|
||||||
pthread_cond_t condProduce;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The thread attributes.
|
|
||||||
*/
|
|
||||||
pthread_attr_t threadAttr;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The threads for the sinks.
|
|
||||||
*/
|
|
||||||
ThreadData * threads;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Signal if we're running or not, so the threads no if to stop.
|
|
||||||
*/
|
|
||||||
bool running;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag to show if the connector should try to reconnect if
|
|
||||||
* the connection is dropped on the other side.
|
|
||||||
*/
|
|
||||||
bool reconnect;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The buffer of information presented to each thread.
|
|
||||||
*/
|
|
||||||
unsigned char * dataBuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The amount of information presented to each thread.
|
|
||||||
*/
|
|
||||||
unsigned int dataSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object.
|
|
||||||
*
|
|
||||||
* @param reconnect flag to indicate if the connector should
|
|
||||||
* try to reconnect if the connection was
|
|
||||||
* dropped by the other end
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( bool reconnect ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-initialize the object.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
strip ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
MultiThreadedConnector ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor based on a Source.
|
|
||||||
*
|
|
||||||
* @param source the source to connect to the sinks.
|
|
||||||
* @param reconnect flag to indicate if the connector should
|
|
||||||
* try to reconnect if the connection was
|
|
||||||
* dropped by the other end
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
MultiThreadedConnector ( Source * source,
|
|
||||||
bool reconnect )
|
|
||||||
throw ( Exception )
|
|
||||||
: Connector( source )
|
|
||||||
{
|
|
||||||
init(reconnect);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor based on a Source and a Sink.
|
|
||||||
*
|
|
||||||
* @param source the source to connect to the sinks.
|
|
||||||
* @param sink a sink to connect to the source.
|
|
||||||
* @param reconnect flag to indicate if the connector should
|
|
||||||
* try to reconnect if the connection was
|
|
||||||
* dropped by the other end
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
MultiThreadedConnector ( Source * source,
|
|
||||||
Sink * sink,
|
|
||||||
bool reconnect )
|
|
||||||
throw ( Exception )
|
|
||||||
: Connector( source, sink)
|
|
||||||
{
|
|
||||||
init(reconnect);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor.
|
|
||||||
*
|
|
||||||
* @param connector the object to copy.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
MultiThreadedConnector ( const MultiThreadedConnector & connector )
|
|
||||||
throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~MultiThreadedConnector( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param connector the object to assign to this one.
|
|
||||||
* @return a reference to this object.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual MultiThreadedConnector &
|
|
||||||
operator= ( const MultiThreadedConnector & connector )
|
|
||||||
throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open the connector. Opens the Source and the Sinks if necessary.
|
|
||||||
*
|
|
||||||
* @return true if opening was successful, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
open ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transfer a given amount of data from the Source to all the
|
|
||||||
* Sinks attached.
|
|
||||||
* If an attached Sink closes or encounteres an error during the
|
|
||||||
* process, it is detached and the function carries on with the
|
|
||||||
* rest of the Sinks. If no Sinks remain, or an error is encountered
|
|
||||||
* with the Source, the function returns prematurely.
|
|
||||||
*
|
|
||||||
* @param bytes the amount of data to transfer, in bytes.
|
|
||||||
* If 0, transfer forever.
|
|
||||||
* @param bufSize the size of the buffer to use for transfering.
|
|
||||||
* This amount of data is read from the Source and
|
|
||||||
* written to each Sink on each turn.
|
|
||||||
* @param sec the number of seconds to wait for the Source to have
|
|
||||||
* data available in each turn, and the number of seconds
|
|
||||||
* to wait for the Sinks to accept data.
|
|
||||||
* @param usec the number of micros seconds to wait for the Source to
|
|
||||||
* have data available in each turn, and the number of
|
|
||||||
* micro seconds to wait for the Sinks to accept data.
|
|
||||||
* @return the number of bytes read from the Source.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual unsigned int
|
|
||||||
transfer ( unsigned long bytes,
|
|
||||||
unsigned int bufSize,
|
|
||||||
unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Signal to each sink we have that they need to cut what they are
|
|
||||||
* doing, and start again. For FileSinks, this usually means to
|
|
||||||
* save the archive file recorded so far, and start a new archive
|
|
||||||
* file.
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
cut ( void ) throw ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the Connector. The Source and all Sinks are closed.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
close ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the worker function for each thread.
|
|
||||||
* This function has to return fast
|
|
||||||
*
|
|
||||||
* @param ixSink the index of the sink this thread works on.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
sinkThread( int ixSink );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* MULTI_THREADED_CONNECTOR_H */
|
|
||||||
|
|
|
@ -1,315 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : OssDspSource.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <unistd.h>
|
|
||||||
#else
|
|
||||||
#error need unistd.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#else
|
|
||||||
#error need string.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#else
|
|
||||||
#error need sys/types.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_STAT_H
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#else
|
|
||||||
#error need sys/stat.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_FCNTL_H
|
|
||||||
#include <fcntl.h>
|
|
||||||
#else
|
|
||||||
#error need fcntl.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TIME_H
|
|
||||||
#include <sys/time.h>
|
|
||||||
#else
|
|
||||||
#error need sys/time.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_IOCTL_H
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#else
|
|
||||||
#error need sys/ioctl.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SIGNAL_H
|
|
||||||
#include <signal.h>
|
|
||||||
#else
|
|
||||||
#error need signal.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_SOUNDCARD_H
|
|
||||||
#include <sys/soundcard.h>
|
|
||||||
#else
|
|
||||||
#error need sys/soundcard.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "Util.h"
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "OssDspSource.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Define the natural endiannes of 16 bit recording if not defined,
|
|
||||||
* based on the endiannes of the system
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
#ifndef AFMT_S16_NE
|
|
||||||
# ifdef WORDS_BIGENDIAN
|
|
||||||
# define AFMT_S16_NE AFMT_S16_BE
|
|
||||||
# else
|
|
||||||
# define AFMT_S16_NE AFMT_S16_LE
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Tell if source id big endian
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
OssDspSource :: isBigEndian ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return AFMT_S16_NE == AFMT_S16_BE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
OssDspSource :: init ( const char * name ) throw ( Exception )
|
|
||||||
{
|
|
||||||
fileName = Util::strDup( name);
|
|
||||||
fileDescriptor = 0;
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* De-initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
OssDspSource :: strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Open the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
OssDspSource :: open ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
int format;
|
|
||||||
int i;
|
|
||||||
unsigned int u;
|
|
||||||
|
|
||||||
if ( isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( getBitsPerSample() ) {
|
|
||||||
case 8:
|
|
||||||
format = AFMT_U8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 16:
|
|
||||||
format = AFMT_S16_NE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (fileDescriptor = ::open( fileName, O_RDONLY)) == -1 ) {
|
|
||||||
fileDescriptor = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = format;
|
|
||||||
if ( ioctl( fileDescriptor, SNDCTL_DSP_SETFMT, &i) == -1 ||
|
|
||||||
i != format ) {
|
|
||||||
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "can't set format", i);
|
|
||||||
}
|
|
||||||
|
|
||||||
u = getChannel();
|
|
||||||
if ( ioctl( fileDescriptor, SNDCTL_DSP_CHANNELS, &u) == -1 ||
|
|
||||||
u != getChannel() ) {
|
|
||||||
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "can't set channels", u);
|
|
||||||
}
|
|
||||||
|
|
||||||
u = getSampleRate();
|
|
||||||
if ( ioctl( fileDescriptor, SNDCTL_DSP_SPEED, &u) == -1 ) {
|
|
||||||
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"can't set soundcard recording sample rate", u);
|
|
||||||
}
|
|
||||||
if ( u != getSampleRate() ) {
|
|
||||||
reportEvent( 2, "sound card recording sample rate set to ", u,
|
|
||||||
" while trying to set it to ", getSampleRate());
|
|
||||||
reportEvent( 2, "this is probably not a problem, but a slight "
|
|
||||||
"drift in the sound card driver");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Check wether read() would return anything
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
OssDspSource :: canRead ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception )
|
|
||||||
{
|
|
||||||
fd_set fdset;
|
|
||||||
struct timespec timespec;
|
|
||||||
sigset_t sigset;
|
|
||||||
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);
|
|
||||||
|
|
||||||
timespec.tv_sec = sec;
|
|
||||||
timespec.tv_nsec = usec * 1000L;
|
|
||||||
|
|
||||||
// mask out SIGUSR1, as we're expecting that signal for other reasons
|
|
||||||
sigemptyset(&sigset);
|
|
||||||
sigaddset(&sigset, SIGUSR1);
|
|
||||||
|
|
||||||
ret = pselect( fileDescriptor + 1, &fdset, NULL, NULL, ×pec, &sigset);
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
|
@ -1,255 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : OssDspSource.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
#ifndef OSS_DSP_SOURCE_H
|
|
||||||
#define OSS_DSP_SOURCE_H
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#error This is a C++ include file
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#include "Reporter.h"
|
|
||||||
#include "AudioSource.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An audio input based on /dev/dsp-like raw devices
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class OssDspSource : public AudioSource, public virtual Reporter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The file name of the OSS DSP device (e.g. /dev/dsp or /dev/dsp0).
|
|
||||||
*/
|
|
||||||
char * fileName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The low-level file descriptor of the OSS DSP device.
|
|
||||||
*/
|
|
||||||
int fileDescriptor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates wether the low-level OSS DSP device is in a recording
|
|
||||||
* state.
|
|
||||||
*/
|
|
||||||
bool running;
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
OssDspSource ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object
|
|
||||||
*
|
|
||||||
* @param name the file name of the OSS DSP device.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( const char * name ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-iitialize the object
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
strip ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param name the file name of the OSS DSP device
|
|
||||||
* (e.g. /dev/dsp or /dev/dsp0).
|
|
||||||
* @param sampleRate samples per second (e.g. 44100 for 44.1kHz).
|
|
||||||
* @param bitsPerSample bits per sample (e.g. 16 bits).
|
|
||||||
* @param channel number of channels of the audio source
|
|
||||||
* (e.g. 1 for mono, 2 for stereo, etc.).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
OssDspSource ( const char * name,
|
|
||||||
int sampleRate = 44100,
|
|
||||||
int bitsPerSample = 16,
|
|
||||||
int channel = 2 )
|
|
||||||
throw ( Exception )
|
|
||||||
|
|
||||||
: AudioSource( sampleRate, bitsPerSample, channel)
|
|
||||||
{
|
|
||||||
init( name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy Constructor.
|
|
||||||
*
|
|
||||||
* @param ods the object to copy.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
OssDspSource ( const OssDspSource & ods ) throw ( Exception )
|
|
||||||
: AudioSource( ods )
|
|
||||||
{
|
|
||||||
init( ods.fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~OssDspSource ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param ds the object to assign to this one.
|
|
||||||
* @return a reference to this object.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual OssDspSource &
|
|
||||||
operator= ( const OssDspSource & ds ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &ds ) {
|
|
||||||
strip();
|
|
||||||
AudioSource::operator=( ds);
|
|
||||||
init( ds.fileName);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tell if the data from this source comes in big or little endian.
|
|
||||||
*
|
|
||||||
* @return true if the source is big endian, false otherwise
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
isBigEndian ( void ) const throw ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open the OssDspSource.
|
|
||||||
* This does not put the OSS DSP device into recording mode.
|
|
||||||
* To start getting samples, call either canRead() or read().
|
|
||||||
*
|
|
||||||
* @return true if opening was successful, false otherwise
|
|
||||||
* @exception Exception
|
|
||||||
*
|
|
||||||
* @see #canRead
|
|
||||||
* @see #read
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
open ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the OssDspSource is open.
|
|
||||||
*
|
|
||||||
* @return true if the OssDspSource is open, false otherwise.
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isOpen ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return fileDescriptor != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the OssDspSource can be read from.
|
|
||||||
* Blocks until the specified time for data to be available.
|
|
||||||
* Puts the OSS DSP device into recording mode.
|
|
||||||
*
|
|
||||||
* @param sec the maximum seconds to block.
|
|
||||||
* @param usec micro seconds to block after the full seconds.
|
|
||||||
* @return true if the OssDspSource is ready to be read from,
|
|
||||||
* false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
canRead ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read from the OssDspSource.
|
|
||||||
* Puts the OSS DSP device into recording mode.
|
|
||||||
*
|
|
||||||
* @param buf the buffer to read into.
|
|
||||||
* @param len the number of bytes to read into buf
|
|
||||||
* @return the number of bytes read (may be less than len).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual unsigned int
|
|
||||||
read ( void * buf,
|
|
||||||
unsigned int len ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the OssDspSource.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
close ( void ) throw ( Exception );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* OSS_DSP_SOURCE_H */
|
|
||||||
|
|
|
@ -1,296 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : Ref.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* #include "Ref.h"
|
|
||||||
* #include "Referable.h"
|
|
||||||
*
|
|
||||||
* class A : public virtual Referable;
|
|
||||||
*
|
|
||||||
* ...
|
|
||||||
*
|
|
||||||
* A * a = new A();
|
|
||||||
* Ref<A> ref1 = a; // 1 reference to a
|
|
||||||
* Ref<A> ref2 = ref1; // 2 references to a
|
|
||||||
*
|
|
||||||
* ref1 = 0; // 1 reference to a
|
|
||||||
* ref2 = 0; // at this point object a is destroyed
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* Based on Tima Saarinen's work,
|
|
||||||
* http://gamma.nic.fi/~timosa/comp/refcount.html
|
|
||||||
*
|
|
||||||
* @ref Referable
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
template <class T>
|
|
||||||
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<T> & other ) throw ( Exception )
|
|
||||||
{
|
|
||||||
object = NULL;
|
|
||||||
set( other.object);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor based on an object to reference.
|
|
||||||
*
|
|
||||||
* @param obj the object to reference.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
Ref ( T * obj ) throw ( Exception )
|
|
||||||
{
|
|
||||||
object = obj;
|
|
||||||
obj->increaseReferenceCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~Ref ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
set( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Operator overload to make the reference seem like a pointer.
|
|
||||||
*
|
|
||||||
* @return the pointer to the object referenced.
|
|
||||||
*/
|
|
||||||
inline T*
|
|
||||||
operator->() const throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !object ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"reference to NULL object");
|
|
||||||
}
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param other the Ref to assign to this one.
|
|
||||||
* @return a reference to this Ref.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline Ref<T> &
|
|
||||||
operator= ( Ref<T> 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<T> &
|
|
||||||
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<T> & 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<T> & other ) const throw ()
|
|
||||||
{
|
|
||||||
return object != other.object;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* REF_H */
|
|
||||||
|
|
|
@ -1,170 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : Referable.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* class A : public virtual Referable
|
|
||||||
* {
|
|
||||||
* ...
|
|
||||||
* };
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @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 */
|
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell Reporter
|
|
||||||
|
|
||||||
File : Reporter.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <iostream>
|
|
||||||
|
|
||||||
#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 */
|
|
||||||
|
|
||||||
|
|
|
@ -1,305 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell Reporter
|
|
||||||
|
|
||||||
File : Reporter.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <unistd.h>
|
|
||||||
#else
|
|
||||||
#error need unistd.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_TIME_H
|
|
||||||
#include <time.h>
|
|
||||||
#else
|
|
||||||
#error need time.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
|
|
||||||
#include "Exception.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class for reporting events. All objects of this class share
|
|
||||||
* the same verbosity level. Typical usage is to inherit this class
|
|
||||||
* and use the report() function to report events. Only reports
|
|
||||||
* which are of suffucient importance are really reported.
|
|
||||||
*
|
|
||||||
* The default verbosity is 1, and the default ostream is cout.
|
|
||||||
*
|
|
||||||
* Known problems: this class is not thread-safe.
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class Reporter
|
|
||||||
{
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verbosity level shared among all Reporter objects
|
|
||||||
*/
|
|
||||||
static unsigned int verbosity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The output stream to report to.
|
|
||||||
*/
|
|
||||||
static std::ostream * os;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print timestamp for every report only if verbosity level
|
|
||||||
* is above this value.
|
|
||||||
*/
|
|
||||||
static const unsigned int prefixVerbosity = 3;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print a prefix to each report.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
printPrefix( void ) throw ()
|
|
||||||
{
|
|
||||||
if ( verbosity > prefixVerbosity ) {
|
|
||||||
char str[32];
|
|
||||||
time_t now;
|
|
||||||
|
|
||||||
now = time(NULL);
|
|
||||||
strftime( str, 32, "%d-%b-%Y %H:%M:%S ", localtime(&now) );
|
|
||||||
(*(Reporter::os)) << str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~Reporter ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
(Reporter::os)->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the verbosity level. This sets the verbosity for all
|
|
||||||
* Reporter objects.
|
|
||||||
*
|
|
||||||
* @param verbosity the new verbosity level.
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
setReportVerbosity ( unsigned int verbosity ) throw ()
|
|
||||||
{
|
|
||||||
Reporter::verbosity = verbosity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the verbosity level.
|
|
||||||
*
|
|
||||||
* @return the current verbosity level.
|
|
||||||
*/
|
|
||||||
static inline unsigned int
|
|
||||||
getReportVerbosity ( void ) throw ()
|
|
||||||
{
|
|
||||||
return Reporter::verbosity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the output stream to report to. This setting effects all
|
|
||||||
* Reporter objects.
|
|
||||||
*
|
|
||||||
* @param os the output stream
|
|
||||||
*/
|
|
||||||
static inline void
|
|
||||||
setReportOutputStream ( std::ostream & os ) throw ()
|
|
||||||
{
|
|
||||||
Reporter::os = &os;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the output stream to report to.
|
|
||||||
*
|
|
||||||
* @return the output stream
|
|
||||||
*/
|
|
||||||
static inline std::ostream &
|
|
||||||
getReportOutputStream ( void ) throw ()
|
|
||||||
{
|
|
||||||
return *(Reporter::os);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report an event with a given verbosity.
|
|
||||||
*
|
|
||||||
* @param verbosity the importance of the event, with 0 being
|
|
||||||
* the most important.
|
|
||||||
* @param t the object to report. Must have an
|
|
||||||
* <code>ostream & operator<<( ostream&, const T)</code>
|
|
||||||
* operator overload.
|
|
||||||
*/
|
|
||||||
template<class T>
|
|
||||||
static inline void
|
|
||||||
reportEvent ( unsigned int verbosity,
|
|
||||||
const T t ) throw ()
|
|
||||||
{
|
|
||||||
if ( Reporter::verbosity >= verbosity ) {
|
|
||||||
printPrefix();
|
|
||||||
(*(Reporter::os)) << t << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report an event with a given verbosity.
|
|
||||||
*
|
|
||||||
* @param verbosity the importance of the event, with 0 being
|
|
||||||
* the most important.
|
|
||||||
* @param t the object 1 to report. Must have an
|
|
||||||
* <code>ostream & operator<<( ostream&, const T)</code>
|
|
||||||
* operator overload.
|
|
||||||
* @param u the object 2 to report. Must have an
|
|
||||||
* <code>ostream & operator<<( ostream&, const U)</code>
|
|
||||||
* operator overload.
|
|
||||||
*/
|
|
||||||
template<class T, class U>
|
|
||||||
inline void
|
|
||||||
static reportEvent ( unsigned int verbosity,
|
|
||||||
const T t,
|
|
||||||
const U u ) throw ()
|
|
||||||
{
|
|
||||||
if ( Reporter::verbosity >= verbosity ) {
|
|
||||||
printPrefix();
|
|
||||||
(*(Reporter::os)) << t << " "
|
|
||||||
<< u << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report an event with a given verbosity.
|
|
||||||
*
|
|
||||||
* @param verbosity the importance of the event, with 0 being
|
|
||||||
* the most important.
|
|
||||||
* @param t the object 1 to report. Must have an
|
|
||||||
* <code>ostream & operator<<( ostream&, const T)</code>
|
|
||||||
* operator overload.
|
|
||||||
* @param u the object 2 to report. Must have an
|
|
||||||
* <code>ostream & operator<<( ostream&, const U)</code>
|
|
||||||
* operator overload.
|
|
||||||
* @param v the object 3 to report. Must have an
|
|
||||||
* <code>ostream & operator<<( ostream&, const V)</code>
|
|
||||||
* operator overload.
|
|
||||||
*/
|
|
||||||
template<class T, class U, class V>
|
|
||||||
static inline void
|
|
||||||
reportEvent ( unsigned int verbosity,
|
|
||||||
const T t,
|
|
||||||
const U u,
|
|
||||||
const V v ) throw ()
|
|
||||||
{
|
|
||||||
if ( Reporter::verbosity >= verbosity ) {
|
|
||||||
printPrefix();
|
|
||||||
(*(Reporter::os)) << t << " "
|
|
||||||
<< u << " "
|
|
||||||
<< v << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Report an event with a given verbosity.
|
|
||||||
*
|
|
||||||
* @param verbosity the importance of the event, with 0 being
|
|
||||||
* the most important.
|
|
||||||
* @param t the object 1 to report. Must have an
|
|
||||||
* <code>ostream & operator<<( ostream&, const T)</code>
|
|
||||||
* operator overload.
|
|
||||||
* @param u the object 2 to report. Must have an
|
|
||||||
* <code>ostream & operator<<( ostream&, const U)</code>
|
|
||||||
* operator overload.
|
|
||||||
* @param v the object 3 to report. Must have an
|
|
||||||
* <code>ostream & operator<<( ostream&, const V)</code>
|
|
||||||
* operator overload.
|
|
||||||
* @param w the object 4 to report. Must have an
|
|
||||||
* <code>ostream & operator<<( ostream&, const W)</code>
|
|
||||||
* operator overload.
|
|
||||||
*/
|
|
||||||
template<class T, class U, class V, class W>
|
|
||||||
static inline void
|
|
||||||
reportEvent ( unsigned int verbosity,
|
|
||||||
const T t,
|
|
||||||
const U u,
|
|
||||||
const V v,
|
|
||||||
const W w ) throw ()
|
|
||||||
{
|
|
||||||
if ( Reporter::verbosity >= verbosity ) {
|
|
||||||
printPrefix();
|
|
||||||
(*(Reporter::os)) << t << " "
|
|
||||||
<< u << " "
|
|
||||||
<< v << " "
|
|
||||||
<< w << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* REPORTER_H */
|
|
||||||
|
|
|
@ -1,328 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000 Tyrell Corporation.
|
|
||||||
Copyright (c) 2006 Clyde Stubbs.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : SerialUlaw.cpp
|
|
||||||
Version : $Revision: 1.13 $
|
|
||||||
Author : $Author: darkeye $
|
|
||||||
Location : $Source: /cvsroot/darkice/darkice/src/SerialUlaw.cpp,v $
|
|
||||||
|
|
||||||
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 "SerialUlaw.h"
|
|
||||||
|
|
||||||
#ifdef SUPPORT_SERIAL_ULAW
|
|
||||||
// only compile this code if there's support for it
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#else
|
|
||||||
#error need unistd.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#else
|
|
||||||
#error need string.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#else
|
|
||||||
#error need sys/types.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_STAT_H
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#else
|
|
||||||
#error need sys/stat.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_FCNTL_H
|
|
||||||
#include <fcntl.h>
|
|
||||||
#else
|
|
||||||
#error need fcntl.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TIME_H
|
|
||||||
#include <sys/time.h>
|
|
||||||
#else
|
|
||||||
#error need sys/time.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_IOCTL_H
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#else
|
|
||||||
#error need sys/ioctl.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS_H
|
|
||||||
#include <termios.h>
|
|
||||||
#else
|
|
||||||
#error need termios.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "Util.h"
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "SerialUlaw.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Ulaw decode table
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static unsigned int ulawdecode[256] =
|
|
||||||
{
|
|
||||||
0x8284,0x8684,0x8a84,0x8e84,0x9284,0x9684,0x9a84,0x9e84,
|
|
||||||
0xa284,0xa684,0xaa84,0xae84,0xb284,0xb684,0xba84,0xbe84,
|
|
||||||
0xc184,0xc384,0xc584,0xc784,0xc984,0xcb84,0xcd84,0xcf84,
|
|
||||||
0xd184,0xd384,0xd584,0xd784,0xd984,0xdb84,0xdd84,0xdf84,
|
|
||||||
0xe104,0xe204,0xe304,0xe404,0xe504,0xe604,0xe704,0xe804,
|
|
||||||
0xe904,0xea04,0xeb04,0xec04,0xed04,0xee04,0xef04,0xf004,
|
|
||||||
0xf0c4,0xf144,0xf1c4,0xf244,0xf2c4,0xf344,0xf3c4,0xf444,
|
|
||||||
0xf4c4,0xf544,0xf5c4,0xf644,0xf6c4,0xf744,0xf7c4,0xf844,
|
|
||||||
0xf8a4,0xf8e4,0xf924,0xf964,0xf9a4,0xf9e4,0xfa24,0xfa64,
|
|
||||||
0xfaa4,0xfae4,0xfb24,0xfb64,0xfba4,0xfbe4,0xfc24,0xfc64,
|
|
||||||
0xfc94,0xfcb4,0xfcd4,0xfcf4,0xfd14,0xfd34,0xfd54,0xfd74,
|
|
||||||
0xfd94,0xfdb4,0xfdd4,0xfdf4,0xfe14,0xfe34,0xfe54,0xfe74,
|
|
||||||
0xfe8c,0xfe9c,0xfeac,0xfebc,0xfecc,0xfedc,0xfeec,0xfefc,
|
|
||||||
0xff0c,0xff1c,0xff2c,0xff3c,0xff4c,0xff5c,0xff6c,0xff7c,
|
|
||||||
0xff88,0xff90,0xff98,0xffa0,0xffa8,0xffb0,0xffb8,0xffc0,
|
|
||||||
0xffc8,0xffd0,0xffd8,0xffe0,0xffe8,0xfff0,0xfff8,0x0000,
|
|
||||||
0x7d7c,0x797c,0x757c,0x717c,0x6d7c,0x697c,0x657c,0x617c,
|
|
||||||
0x5d7c,0x597c,0x557c,0x517c,0x4d7c,0x497c,0x457c,0x417c,
|
|
||||||
0x3e7c,0x3c7c,0x3a7c,0x387c,0x367c,0x347c,0x327c,0x307c,
|
|
||||||
0x2e7c,0x2c7c,0x2a7c,0x287c,0x267c,0x247c,0x227c,0x207c,
|
|
||||||
0x1efc,0x1dfc,0x1cfc,0x1bfc,0x1afc,0x19fc,0x18fc,0x17fc,
|
|
||||||
0x16fc,0x15fc,0x14fc,0x13fc,0x12fc,0x11fc,0x10fc,0x0ffc,
|
|
||||||
0x0f3c,0x0ebc,0x0e3c,0x0dbc,0x0d3c,0x0cbc,0x0c3c,0x0bbc,
|
|
||||||
0x0b3c,0x0abc,0x0a3c,0x09bc,0x093c,0x08bc,0x083c,0x07bc,
|
|
||||||
0x075c,0x071c,0x06dc,0x069c,0x065c,0x061c,0x05dc,0x059c,
|
|
||||||
0x055c,0x051c,0x04dc,0x049c,0x045c,0x041c,0x03dc,0x039c,
|
|
||||||
0x036c,0x034c,0x032c,0x030c,0x02ec,0x02cc,0x02ac,0x028c,
|
|
||||||
0x026c,0x024c,0x022c,0x020c,0x01ec,0x01cc,0x01ac,0x018c,
|
|
||||||
0x0174,0x0164,0x0154,0x0144,0x0134,0x0124,0x0114,0x0104,
|
|
||||||
0x00f4,0x00e4,0x00d4,0x00c4,0x00b4,0x00a4,0x0094,0x0084,
|
|
||||||
0x0078,0x0070,0x0068,0x0060,0x0058,0x0050,0x0048,0x0040,
|
|
||||||
0x0038,0x0030,0x0028,0x0020,0x0018,0x0010,0x0008,0x0000,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Tell if source id big endian
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
SerialUlaw :: isBigEndian ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
SerialUlaw :: init ( const char * name ) throw ( Exception )
|
|
||||||
{
|
|
||||||
fileName = Util::strDup( name);
|
|
||||||
fileDescriptor = 0;
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* De-initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
SerialUlaw :: strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Open the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
SerialUlaw :: open ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
struct termios ts;
|
|
||||||
|
|
||||||
if ( isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( getBitsPerSample() ) {
|
|
||||||
case 16:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getChannel() != 1) {
|
|
||||||
reportEvent(3, "Only mono input supported for Serial ULaw");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (getSampleRate() != 8000) {
|
|
||||||
reportEvent(3, "Only 8000 Hz sample rate supported for Serial ULaw");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (fileDescriptor = ::open( fileName, O_RDONLY)) == -1 ) {
|
|
||||||
fileDescriptor = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tcgetattr(fileDescriptor, &ts) < 0) {
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "can't get tty settings");
|
|
||||||
}
|
|
||||||
|
|
||||||
cfsetispeed(&ts, B115200);
|
|
||||||
cfmakeraw(&ts);
|
|
||||||
ts.c_cflag |= CLOCAL;
|
|
||||||
if(tcsetattr(fileDescriptor, TCSANOW, &ts) < 0) {
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "can't set tty settings");
|
|
||||||
}
|
|
||||||
|
|
||||||
tcflush(fileDescriptor, TCIFLUSH);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Check whether read() would return anything
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
SerialUlaw :: canRead ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception )
|
|
||||||
{
|
|
||||||
fd_set fdset;
|
|
||||||
struct timeval tv;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO( &fdset);
|
|
||||||
FD_SET( fileDescriptor, &fdset);
|
|
||||||
tv.tv_sec = sec;
|
|
||||||
tv.tv_usec = usec;
|
|
||||||
|
|
||||||
ret = select( fileDescriptor + 1, &fdset, NULL, NULL, &tv);
|
|
||||||
|
|
||||||
if ( ret == -1 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "select error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Read from the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
SerialUlaw :: read ( void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
ssize_t ret;
|
|
||||||
unsigned char ubuf[256], * ptr;
|
|
||||||
int i, plen;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
ptr = (unsigned char *)buf;
|
|
||||||
while(len > 1) {
|
|
||||||
plen = sizeof(ubuf);
|
|
||||||
if (plen > (int)len/2) {
|
|
||||||
plen = len/2;
|
|
||||||
}
|
|
||||||
plen = ::read( fileDescriptor, ubuf, plen);
|
|
||||||
if(plen < 0) {
|
|
||||||
perror("read");
|
|
||||||
throw Exception( __FILE__, __LINE__, "read error");
|
|
||||||
}
|
|
||||||
for(i = 0 ; i != plen ; i++) {
|
|
||||||
*ptr++ = ulawdecode[ubuf[i]] & 0xFF;
|
|
||||||
*ptr++ = ulawdecode[ubuf[i]] >> 8;
|
|
||||||
}
|
|
||||||
len -= plen*2;
|
|
||||||
ret += plen*2;
|
|
||||||
}
|
|
||||||
|
|
||||||
running = true;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Close the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
SerialUlaw :: close ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
::close( fileDescriptor);
|
|
||||||
fileDescriptor = 0;
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // SUPPORT_SERIAL_ULAW
|
|
|
@ -1,255 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
Copyright (c) 2007 Clyde Stubbs
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : SerialUlaw.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 SERIAL_ULAW_SOURCE_H
|
|
||||||
#define SERIAL_ULAW_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: darkeye $
|
|
||||||
* @version $Revision: 1.7 $
|
|
||||||
*/
|
|
||||||
class SerialUlaw : 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
|
|
||||||
SerialUlaw ( 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
|
|
||||||
SerialUlaw ( const char * name,
|
|
||||||
int sampleRate = 44100,
|
|
||||||
int bitsPerSample = 16,
|
|
||||||
int channel = 2 )
|
|
||||||
throw ( Exception )
|
|
||||||
|
|
||||||
: AudioSource( sampleRate, bitsPerSample, channel)
|
|
||||||
{
|
|
||||||
init( name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy Constructor.
|
|
||||||
*
|
|
||||||
* @param ods the object to copy.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
SerialUlaw ( const SerialUlaw & ods ) throw ( Exception )
|
|
||||||
: AudioSource( ods )
|
|
||||||
{
|
|
||||||
init( ods.fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~SerialUlaw ( 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 SerialUlaw &
|
|
||||||
operator= ( const SerialUlaw & ds ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &ds ) {
|
|
||||||
strip();
|
|
||||||
AudioSource::operator=( ds);
|
|
||||||
init( ds.fileName);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tell if the data from this source comes in big or little endian.
|
|
||||||
*
|
|
||||||
* @return true if the source is big endian, false otherwise
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
isBigEndian ( void ) const throw ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open the SerialUlaw.
|
|
||||||
* 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 SerialUlaw is open.
|
|
||||||
*
|
|
||||||
* @return true if the SerialUlaw is open, false otherwise.
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isOpen ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return fileDescriptor != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the SerialUlaw 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 SerialUlaw is ready to be read from,
|
|
||||||
* false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
canRead ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read from the SerialUlaw.
|
|
||||||
* 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 SerialUlaw.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
close ( void ) throw ( Exception );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* SERIAL_ULAW_SOURCE_H */
|
|
|
@ -1,259 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 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 <stdio.h>
|
|
||||||
#else
|
|
||||||
#error need stdio.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#else
|
|
||||||
#error need string.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_MATH_H
|
|
||||||
#include <math.h>
|
|
||||||
#else
|
|
||||||
#error need math.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
|
|
||||||
#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,
|
|
||||||
const char * mountPoint )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
this->irc = irc ? Util::strDup( irc) : 0;
|
|
||||||
this->aim = aim ? Util::strDup( aim) : 0;
|
|
||||||
this->icq = icq ? Util::strDup( icq) : 0;
|
|
||||||
this->mountPoint = mountPoint ? Util::strDup( mountPoint ) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* De-initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
ShoutCast :: strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( irc ) {
|
|
||||||
delete[] irc;
|
|
||||||
}
|
|
||||||
if ( aim ) {
|
|
||||||
delete[] aim;
|
|
||||||
}
|
|
||||||
if ( icq ) {
|
|
||||||
delete[] icq;
|
|
||||||
}
|
|
||||||
if (mountPoint ){
|
|
||||||
delete[] mountPoint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* 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;
|
|
||||||
bool needsMountPoint = false;
|
|
||||||
const char * mountPoint = getMountPoint();
|
|
||||||
|
|
||||||
|
|
||||||
if ( !source->isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ( !sink->isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We will add SOURCE only if really needed: if the mountPoint is not null
|
|
||||||
// and is different of "/". This is to keep maximum compatibility with
|
|
||||||
// NullSoft Shoutcast server.
|
|
||||||
if (mountPoint != 0L
|
|
||||||
&& strlen(mountPoint) > 0 && 0 != strcmp("/", mountPoint)) {
|
|
||||||
needsMountPoint = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostringstream os;
|
|
||||||
|
|
||||||
if (needsMountPoint) {
|
|
||||||
os << "SOURCE ";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* first line is the password in itself */
|
|
||||||
os << getPassword();
|
|
||||||
os << "\n";
|
|
||||||
|
|
||||||
// send the mount point
|
|
||||||
if (needsMountPoint) {
|
|
||||||
os << " ";
|
|
||||||
if (strncmp("/", mountPoint, 1) != 0) {
|
|
||||||
os << "/";
|
|
||||||
}
|
|
||||||
os << mountPoint;
|
|
||||||
os << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
str = os.str().c_str();
|
|
||||||
|
|
||||||
// Ok, now we send login which will be different of classical Shoutcast
|
|
||||||
// if mountPoint is not null and is different from "/" ...
|
|
||||||
sink->write( str, strlen( str));
|
|
||||||
sink->flush();
|
|
||||||
|
|
||||||
/* read the anticipated response: "OK" */
|
|
||||||
len = source->read( resp, STRBUF_SIZE);
|
|
||||||
reportEvent(8, "server response length: ", len);
|
|
||||||
reportEvent(8, "server response: ", resp);
|
|
||||||
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)) ) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,281 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : ShoutCast.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The optional mountPoint
|
|
||||||
*/
|
|
||||||
char * mountPoint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
* @param mountPoint Optional mount point information
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( const char * irc,
|
|
||||||
const char * aim,
|
|
||||||
const char * icq,
|
|
||||||
const char * mountPoint )
|
|
||||||
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 mountPoint Optional mount point for DSS.
|
|
||||||
* @param name name of the stream.
|
|
||||||
* @param url URL associated with the stream.
|
|
||||||
* @param genre genre of the stream.
|
|
||||||
* @param bitRate bitrate of the stream (e.g. mp3 bitrate).
|
|
||||||
* @param isPublic is the stream public?
|
|
||||||
* @param irc IRC info string for the stream.
|
|
||||||
* @param aim AIM info string for the stream.
|
|
||||||
* @param icq ICQ info string for the stream.
|
|
||||||
* @param streamDump an optional sink to dump the binary stream
|
|
||||||
* data to.
|
|
||||||
* @param bufferDuration duration of the BufferedSink buffer
|
|
||||||
* in seconds.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
ShoutCast ( TcpSocket * socket,
|
|
||||||
const char * password,
|
|
||||||
const char * mountPoint,
|
|
||||||
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, mountPoint );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor.
|
|
||||||
*
|
|
||||||
* @param cs the ShoutCast to copy.
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
ShoutCast( const ShoutCast & cs ) throw ( Exception )
|
|
||||||
: CastSink( cs )
|
|
||||||
{
|
|
||||||
init( cs.getIrc(), cs.getAim(), cs.getIcq(), cs.getMountPoint());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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(), getMountPoint());
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the mount point of the stream on the server.
|
|
||||||
* The mount point can be null if it has not been set
|
|
||||||
* (typical Shoutcast server) or not null (for instance
|
|
||||||
* with Darwin Streaming Server). In that case, the
|
|
||||||
* authentication process will be slightly different.
|
|
||||||
*
|
|
||||||
* @return the mount point of the stream on the server.
|
|
||||||
*/
|
|
||||||
inline const char *
|
|
||||||
getMountPoint ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return mountPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 */
|
|
||||||
|
|
|
@ -1,185 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : Sink.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cut what the sink has been doing so far, and start anew.
|
|
||||||
* This usually means separating the data sent to the sink up
|
|
||||||
* until now, and start saving a new chunk of data.
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
cut ( void ) throw () = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the Sink.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
close ( void ) throw ( Exception ) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* SINK_H */
|
|
||||||
|
|
|
@ -1,277 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : SolarisDspSource.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <unistd.h>
|
|
||||||
#else
|
|
||||||
#error need unistd.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#else
|
|
||||||
#error need string.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#else
|
|
||||||
#error need sys/types.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_STAT_H
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#else
|
|
||||||
#error need sys/stat.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_FCNTL_H
|
|
||||||
#include <fcntl.h>
|
|
||||||
#else
|
|
||||||
#error need fcntl.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TIME_H
|
|
||||||
#include <sys/time.h>
|
|
||||||
#else
|
|
||||||
#error need sys/time.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_IOCTL_H
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#else
|
|
||||||
#error need sys/ioctl.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SIGNAL_H
|
|
||||||
#include <signal.h>
|
|
||||||
#else
|
|
||||||
#error need signal.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined( HAVE_SYS_AUDIO_H )
|
|
||||||
#include <sys/audio.h>
|
|
||||||
#elif defined( HAVE_SYS_AUDIOIO_H )
|
|
||||||
#include <sys/audioio.h>
|
|
||||||
#else
|
|
||||||
#error need sys/audio.h or sys/audioio.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "Util.h"
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "SolarisDspSource.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
SolarisDspSource :: init ( const char * name ) throw ( Exception )
|
|
||||||
{
|
|
||||||
fileName = Util::strDup( name);
|
|
||||||
fileDescriptor = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* De-initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
SolarisDspSource :: strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Open the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
SolarisDspSource :: open ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
audio_info_t audioInfo;
|
|
||||||
|
|
||||||
if ( isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (fileDescriptor = ::open( fileName, O_RDONLY)) == -1 ) {
|
|
||||||
fileDescriptor = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
AUDIO_INITINFO( &audioInfo);
|
|
||||||
audioInfo.record.sample_rate = getSampleRate();
|
|
||||||
audioInfo.record.channels = getChannel();
|
|
||||||
audioInfo.record.precision = getBitsPerSample();
|
|
||||||
audioInfo.record.encoding = AUDIO_ENCODING_LINEAR;
|
|
||||||
// for stupid OpenBSD we need to add the following, as it masks
|
|
||||||
// read/write calls when using -pthread
|
|
||||||
audioInfo.record.pause = 0;
|
|
||||||
|
|
||||||
if ( ioctl( fileDescriptor, AUDIO_SETINFO, &audioInfo) == -1 ) {
|
|
||||||
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__, "ioctl error");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( audioInfo.record.channels != getChannel() ) {
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"can't set channels", audioInfo.record.channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( audioInfo.record.precision != getBitsPerSample() ) {
|
|
||||||
close();
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"can't set bits per sample",
|
|
||||||
audioInfo.record.precision);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( audioInfo.record.sample_rate != getSampleRate() ) {
|
|
||||||
reportEvent( 2, "sound card recording sample rate set to ",
|
|
||||||
audioInfo.record.sample_rate,
|
|
||||||
" while trying to set it to ", getSampleRate());
|
|
||||||
reportEvent( 2, "this is probably not a problem, but a slight "
|
|
||||||
"drift in the sound card driver");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Check wether read() would return anything
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
SolarisDspSource :: canRead ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception )
|
|
||||||
{
|
|
||||||
fd_set fdset;
|
|
||||||
struct timespec timespec;
|
|
||||||
sigset_t sigset;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO( &fdset);
|
|
||||||
FD_SET( fileDescriptor, &fdset);
|
|
||||||
|
|
||||||
timespec.tv_sec = sec;
|
|
||||||
timespec.tv_nsec = usec * 1000L;
|
|
||||||
|
|
||||||
// mask out SIGUSR1, as we're expecting that signal for other reasons
|
|
||||||
sigemptyset(&sigset);
|
|
||||||
sigaddset(&sigset, SIGUSR1);
|
|
||||||
|
|
||||||
ret = pselect( fileDescriptor + 1, &fdset, NULL, NULL, ×pec, &sigset);
|
|
||||||
|
|
||||||
if ( ret == -1 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "select error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Read from the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
SolarisDspSource :: read ( void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ::read( fileDescriptor, buf, len);
|
|
||||||
|
|
||||||
if ( ret == -1 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "read error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Close the audio source
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
SolarisDspSource :: close ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
::close( fileDescriptor);
|
|
||||||
fileDescriptor = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // SUPPORT_SOLARIS_DSP
|
|
||||||
|
|
|
@ -1,257 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : SolarisDspSource.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
#ifndef SOLARIS_DSP_SOURCE_H
|
|
||||||
#define SOLARIS_DSP_SOURCE_H
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#error This is a C++ include file
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#include "Reporter.h"
|
|
||||||
#include "AudioSource.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An audio input based on Solaris /dev/audio devices
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class SolarisDspSource : public AudioSource, public virtual Reporter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The file name of the OSS DSP device (e.g. /dev/audio)
|
|
||||||
*/
|
|
||||||
char * fileName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The low-level file descriptor of the Solaris DSP device.
|
|
||||||
*/
|
|
||||||
int fileDescriptor;
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
SolarisDspSource ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object
|
|
||||||
*
|
|
||||||
* @param name the file name of the Solaris DSP device.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( const char * name ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-iitialize the object
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
strip ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param name the file name of the Solaris DSP device
|
|
||||||
* (e.g. /dev/audio or /dev/sound/0)
|
|
||||||
* @param sampleRate samples per second (e.g. 44100 for 44.1kHz).
|
|
||||||
* @param bitsPerSample bits per sample (e.g. 16 bits).
|
|
||||||
* @param channel number of channels of the audio source
|
|
||||||
* (e.g. 1 for mono, 2 for stereo, etc.).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
SolarisDspSource ( const char * name,
|
|
||||||
int sampleRate = 44100,
|
|
||||||
int bitsPerSample = 16,
|
|
||||||
int channel = 2 )
|
|
||||||
throw ( Exception )
|
|
||||||
|
|
||||||
: AudioSource( sampleRate, bitsPerSample, channel)
|
|
||||||
{
|
|
||||||
init( name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy Constructor.
|
|
||||||
*
|
|
||||||
* @param sds the object to copy.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
SolarisDspSource ( const SolarisDspSource & sds )
|
|
||||||
throw ( Exception )
|
|
||||||
: AudioSource( sds )
|
|
||||||
{
|
|
||||||
init( sds.fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~SolarisDspSource ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param ds the object to assign to this one.
|
|
||||||
* @return a reference to this object.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual SolarisDspSource &
|
|
||||||
operator= ( const SolarisDspSource & ds ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &ds ) {
|
|
||||||
strip();
|
|
||||||
AudioSource::operator=( ds);
|
|
||||||
init( ds.fileName);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tell if the data from this source comes in big or little endian.
|
|
||||||
*
|
|
||||||
* @return true
|
|
||||||
*/
|
|
||||||
virtual inline bool
|
|
||||||
isBigEndian ( void ) const throw ()
|
|
||||||
{
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open the SolarisDspSource.
|
|
||||||
* This does not put the Solaris DSP device into recording mode.
|
|
||||||
* To start getting samples, call either canRead() or read().
|
|
||||||
*
|
|
||||||
* @return true if opening was successful, false otherwise
|
|
||||||
* @exception Exception
|
|
||||||
*
|
|
||||||
* @see #canRead
|
|
||||||
* @see #read
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
open ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the SolarisDspSource is open.
|
|
||||||
*
|
|
||||||
* @return true if the SolarisDspSource is open, false otherwise.
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isOpen ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return fileDescriptor != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the SolarisDspSource can be read from.
|
|
||||||
* Blocks until the specified time for data to be available.
|
|
||||||
* Puts the Solaris DSP device into recording mode.
|
|
||||||
*
|
|
||||||
* @param sec the maximum seconds to block.
|
|
||||||
* @param usec micro seconds to block after the full seconds.
|
|
||||||
* @return true if the SolarisDspSource is ready to be read from,
|
|
||||||
* false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
canRead ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read from the SolarisDspSource.
|
|
||||||
* Puts the Solaris DSP device into recording mode.
|
|
||||||
*
|
|
||||||
* @param buf the buffer to read into.
|
|
||||||
* @param len the number of bytes to read into buf
|
|
||||||
* @return the number of bytes read (may be less than len).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual unsigned int
|
|
||||||
read ( void * buf,
|
|
||||||
unsigned int len ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the SolarisDspSource.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
close ( void ) throw ( Exception );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* SOLARIS_DSP_SOURCE_H */
|
|
||||||
|
|
|
@ -1,171 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : Source.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 */
|
|
||||||
|
|
|
@ -1,417 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : TcpSocket.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <string.h>
|
|
||||||
#else
|
|
||||||
#error need string.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#else
|
|
||||||
#error need sys/types.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_ERRNO_H
|
|
||||||
#include <errno.h>
|
|
||||||
#else
|
|
||||||
#error need errno.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#else
|
|
||||||
#error need sys/socket.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#else
|
|
||||||
#error need netinet/in.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_NETDB_H
|
|
||||||
#include <netdb.h>
|
|
||||||
#else
|
|
||||||
#error need netdb.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#else
|
|
||||||
#error need unistd.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TIME_H
|
|
||||||
#include <sys/time.h>
|
|
||||||
#else
|
|
||||||
#error need sys/time.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SIGNAL_H
|
|
||||||
#include <signal.h>
|
|
||||||
#else
|
|
||||||
#error need signal.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 )
|
|
||||||
{
|
|
||||||
int optval;
|
|
||||||
socklen_t optlen;
|
|
||||||
#ifdef HAVE_ADDRINFO
|
|
||||||
struct addrinfo hints
|
|
||||||
struct addrinfo * ptr;
|
|
||||||
struct sockaddr_storage addr;
|
|
||||||
char portstr[6];
|
|
||||||
#else
|
|
||||||
struct sockaddr_in addr;
|
|
||||||
struct hostent * pHostEntry;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_ADDRINFO
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
|
||||||
hints.ai_family = AF_ANY;
|
|
||||||
snprintf(portstr, sizeof(portstr), "%d", port);
|
|
||||||
|
|
||||||
if (getaddrinfo(host , portstr, &hints, &ptr)) {
|
|
||||||
sockfd = 0;
|
|
||||||
throw Exception( __FILE__, __LINE__, "getaddrinfo error", errno);
|
|
||||||
}
|
|
||||||
memcpy ( addr, ptr->ai_addr, ptr->ai_addrlen);
|
|
||||||
freeaddrinfo(ptr);
|
|
||||||
#else
|
|
||||||
if ( !(pHostEntry = gethostbyname( host)) ) {
|
|
||||||
sockfd = 0;
|
|
||||||
throw Exception( __FILE__, __LINE__, "gethostbyname error", errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset( &addr, 0, sizeof(addr));
|
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
addr.sin_port = htons(port);
|
|
||||||
addr.sin_addr.s_addr = *((long*) pHostEntry->h_addr_list[0]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( (sockfd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1 ) {
|
|
||||||
sockfd = 0;
|
|
||||||
throw Exception( __FILE__, __LINE__, "socket error", errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set TCP keep-alive
|
|
||||||
optval = 1;
|
|
||||||
optlen = sizeof(optval);
|
|
||||||
if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) == -1) {
|
|
||||||
reportEvent(5, "can't set TCP socket keep-alive mode", errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect
|
|
||||||
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 timespec timespec;
|
|
||||||
sigset_t sigset;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO( &fdset);
|
|
||||||
FD_SET( sockfd, &fdset);
|
|
||||||
|
|
||||||
timespec.tv_sec = sec;
|
|
||||||
timespec.tv_nsec = usec * 1000L;
|
|
||||||
|
|
||||||
// mask out SIGUSR1, as we're expecting that signal for other reasons
|
|
||||||
sigemptyset(&sigset);
|
|
||||||
sigaddset(&sigset, SIGUSR1);
|
|
||||||
|
|
||||||
ret = pselect( sockfd + 1, &fdset, NULL, NULL, ×pec, &sigset);
|
|
||||||
|
|
||||||
if ( ret == -1 ) {
|
|
||||||
::close( sockfd);
|
|
||||||
sockfd = 0;
|
|
||||||
throw Exception( __FILE__, __LINE__, "select error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Read from the socket
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
TcpSocket :: read ( void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = recv( sockfd, buf, len, 0);
|
|
||||||
|
|
||||||
if ( ret == -1 ) {
|
|
||||||
switch (errno) {
|
|
||||||
case ECONNRESET:
|
|
||||||
// re-open the socket if it has been reset by the peer
|
|
||||||
close();
|
|
||||||
Util::sleep(1L, 0L);
|
|
||||||
open();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
::close( sockfd);
|
|
||||||
sockfd = 0;
|
|
||||||
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 timespec timespec;
|
|
||||||
sigset_t sigset;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO( &fdset);
|
|
||||||
FD_SET( sockfd, &fdset);
|
|
||||||
|
|
||||||
timespec.tv_sec = sec;
|
|
||||||
timespec.tv_nsec = usec * 1000L;
|
|
||||||
|
|
||||||
// mask out SIGUSR1, as we're expecting that signal for other reasons
|
|
||||||
sigemptyset(&sigset);
|
|
||||||
sigaddset(&sigset, SIGUSR1);
|
|
||||||
|
|
||||||
ret = pselect( sockfd + 1, NULL, &fdset, NULL, ×pec, &sigset);
|
|
||||||
|
|
||||||
if ( ret == -1 ) {
|
|
||||||
::close( sockfd);
|
|
||||||
sockfd = 0;
|
|
||||||
throw Exception( __FILE__, __LINE__, "select error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Write to the socket
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
TcpSocket :: write ( const void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_MSG_NOSIGNAL
|
|
||||||
ret = send( sockfd, buf, len, MSG_NOSIGNAL);
|
|
||||||
#else
|
|
||||||
ret = send( sockfd, buf, len, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( ret == -1 ) {
|
|
||||||
if ( errno == EAGAIN ) {
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
::close( sockfd);
|
|
||||||
sockfd = 0;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,292 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : TcpSocket.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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"
|
|
||||||
#include "Reporter.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A TCP network socket
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class TcpSocket : public Source, public Sink, public virtual Reporter
|
|
||||||
{
|
|
||||||
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 )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cut what the sink has been doing so far, and start anew.
|
|
||||||
* This usually means separating the data sent to the sink up
|
|
||||||
* until now, and start saving a new chunk of data.
|
|
||||||
*
|
|
||||||
* For TcpSocket, this is a no-op.
|
|
||||||
*/
|
|
||||||
inline virtual void
|
|
||||||
cut ( void ) throw ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the TcpSocket.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
close ( void ) throw ( Exception );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* TCP_SOCKET_H */
|
|
||||||
|
|
|
@ -1,301 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : TwoLameLibEncoder.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// compile the whole file only if TwoLame support configured in
|
|
||||||
#ifdef HAVE_TWOLAME_LIB
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "TwoLameLibEncoder.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Initialize the object
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
TwoLameLibEncoder :: init ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
this->twolame_opts = NULL;
|
|
||||||
|
|
||||||
if ( getInBitsPerSample() != 16 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"specified bits per sample not supported",
|
|
||||||
getInBitsPerSample() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( getInChannel() != 1 && getInChannel() != 2 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"unsupported number of input channels for the encoder",
|
|
||||||
getInChannel() );
|
|
||||||
}
|
|
||||||
if ( getOutChannel() != 1 && getOutChannel() != 2 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"unsupported number of output channels for the encoder",
|
|
||||||
getOutChannel() );
|
|
||||||
}
|
|
||||||
if ( getInChannel() < getOutChannel() ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"output channels greater then input channels",
|
|
||||||
getOutChannel() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Open an encoding session
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
TwoLameLibEncoder :: open ( void )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// open the underlying sink
|
|
||||||
if ( !getSink()->open() ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"TwoLAME lib opening underlying sink error");
|
|
||||||
}
|
|
||||||
|
|
||||||
twolame_opts = ::twolame_init();
|
|
||||||
|
|
||||||
// ugly twolame returns -1 in a pointer on allocation errors
|
|
||||||
if ( !twolame_opts ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"TwoLAME lib init error",
|
|
||||||
(long int) twolame_opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( 0 > twolame_set_num_channels( twolame_opts, getInChannel()) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"TwoLAME lib setting channels error",
|
|
||||||
getInChannel() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( 0 > twolame_set_mode( twolame_opts,
|
|
||||||
getOutChannel() == 1 ? TWOLAME_MONO : TWOLAME_JOINT_STEREO) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"TwoLAME lib setting mode error",
|
|
||||||
TWOLAME_JOINT_STEREO );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( 0 > twolame_set_in_samplerate( twolame_opts, getInSampleRate()) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"TwoLAME lib setting input sample rate error",
|
|
||||||
getInSampleRate() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( 0 > twolame_set_out_samplerate( twolame_opts, getOutSampleRate()) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"TwoLAME lib setting output sample rate error",
|
|
||||||
getOutSampleRate() );
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( getOutBitrateMode() ) {
|
|
||||||
|
|
||||||
case cbr: {
|
|
||||||
|
|
||||||
if ( 0 > twolame_set_brate( twolame_opts, getOutBitrate()) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"TwoLAME lib setting output bit rate error",
|
|
||||||
getOutBitrate() );
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"Unsupported bitrate mode." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// let TwoLAME init its own params based on our settings
|
|
||||||
if ( 0 > twolame_init_params( twolame_opts) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"TwoLAME lib initializing params error" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Information about TwoLame's setup
|
|
||||||
if (getReportVerbosity() >= 3) {
|
|
||||||
twolame_print_config( twolame_opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Write data to the encoder
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
TwoLameLibEncoder :: write ( const void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() || len == 0 ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int bitsPerSample = getInBitsPerSample();
|
|
||||||
unsigned int inChannels = getInChannel();
|
|
||||||
|
|
||||||
unsigned int sampleSize = (bitsPerSample / 8) * inChannels;
|
|
||||||
unsigned char * b = (unsigned char*) buf;
|
|
||||||
unsigned int processed = len - (len % sampleSize);
|
|
||||||
unsigned int nSamples = processed / sampleSize;
|
|
||||||
short int * leftBuffer = new short int[nSamples];
|
|
||||||
short int * rightBuffer = new short int[nSamples];
|
|
||||||
|
|
||||||
if ( bitsPerSample == 8 ) {
|
|
||||||
Util::conv8( b, processed, leftBuffer, rightBuffer, inChannels);
|
|
||||||
} else if ( bitsPerSample == 16 ) {
|
|
||||||
Util::conv16( b,
|
|
||||||
processed,
|
|
||||||
leftBuffer,
|
|
||||||
rightBuffer,
|
|
||||||
inChannels,
|
|
||||||
isInBigEndian());
|
|
||||||
} else {
|
|
||||||
delete[] leftBuffer;
|
|
||||||
delete[] rightBuffer;
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"unsupported number of bits per sample for the encoder",
|
|
||||||
bitsPerSample );
|
|
||||||
}
|
|
||||||
|
|
||||||
// data chunk size estimate according to TwoLAME documentation
|
|
||||||
// NOTE: mp2Size is calculated based on the number of input channels
|
|
||||||
// which may be bigger than need, as output channels can be less
|
|
||||||
unsigned int mp2Size = (unsigned int) (1.25 * nSamples + 7200);
|
|
||||||
unsigned char * mp2Buf = new unsigned char[mp2Size];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = twolame_encode_buffer( twolame_opts,
|
|
||||||
leftBuffer,
|
|
||||||
inChannels == 2 ? rightBuffer : leftBuffer,
|
|
||||||
nSamples,
|
|
||||||
mp2Buf,
|
|
||||||
mp2Size );
|
|
||||||
|
|
||||||
delete[] leftBuffer;
|
|
||||||
delete[] rightBuffer;
|
|
||||||
|
|
||||||
if ( ret < 0 ) {
|
|
||||||
reportEvent( 3, "TwoLAME encoding error", ret);
|
|
||||||
delete[] mp2Buf;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int written = getSink()->write( mp2Buf, ret);
|
|
||||||
delete[] mp2Buf;
|
|
||||||
// just let go data that could not be written
|
|
||||||
if ( written < (unsigned int) ret ) {
|
|
||||||
reportEvent( 2,
|
|
||||||
"couldn't write all from encoder to underlying sink",
|
|
||||||
ret - written);
|
|
||||||
}
|
|
||||||
|
|
||||||
return processed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Flush the data from the encoder
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
TwoLameLibEncoder :: flush ( void )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// data chunk size estimate according to TwoLAME documentation
|
|
||||||
unsigned int mp2Size = 7200;
|
|
||||||
unsigned char * mp2Buf = new unsigned char[mp2Size];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = twolame_encode_flush( twolame_opts, mp2Buf, mp2Size );
|
|
||||||
|
|
||||||
unsigned int written = getSink()->write( mp2Buf, ret);
|
|
||||||
delete[] mp2Buf;
|
|
||||||
|
|
||||||
// just let go data that could not be written
|
|
||||||
if ( written < (unsigned int) ret ) {
|
|
||||||
reportEvent( 2,
|
|
||||||
"couldn't write all from encoder to underlying sink",
|
|
||||||
ret - written);
|
|
||||||
}
|
|
||||||
|
|
||||||
getSink()->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Close the encoding session
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
TwoLameLibEncoder :: close ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
flush();
|
|
||||||
twolame_close( &twolame_opts );
|
|
||||||
getSink()->close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // HAVE_TWOLAME_LIB
|
|
||||||
|
|
|
@ -1,367 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : TwoLameLibEncoder.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
#ifndef TWOLAME_LIB_ENCODER_H
|
|
||||||
#define TWOLAME_LIB_ENCODER_H
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#error This is a C++ include file
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_TWOLAME_LIB
|
|
||||||
#include <twolame.h>
|
|
||||||
#else
|
|
||||||
#error configure with twolame
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "Ref.h"
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "Reporter.h"
|
|
||||||
#include "AudioEncoder.h"
|
|
||||||
#include "Sink.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class representing the TwoLame encoder linked as a shared object or as
|
|
||||||
* a static library.
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class TwoLameLibEncoder : public AudioEncoder, public virtual Reporter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TwoLame library global flags
|
|
||||||
*/
|
|
||||||
twolame_options * twolame_opts;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object.
|
|
||||||
*
|
|
||||||
* @param sink the sink to send mp2 output to
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-initialize the object.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline void
|
|
||||||
strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
TwoLameLibEncoder ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param sink the sink to send mp2 output to
|
|
||||||
* @param inSampleRate sample rate of the input.
|
|
||||||
* @param inBitsPerSample number of bits per sample of the input.
|
|
||||||
* @param inChannel number of channels of the input.
|
|
||||||
* @param inBigEndian shows if the input is big or little endian
|
|
||||||
* @param outBitrateMode the bit rate mode of the output.
|
|
||||||
* @param outBitrate bit rate of the output (kbits/sec).
|
|
||||||
* @param outSampleRate sample rate of the output.
|
|
||||||
* If 0, inSampleRate is used.
|
|
||||||
* @param outChannel number of channels of the output.
|
|
||||||
* If 0, inChannel is used.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
TwoLameLibEncoder ( Sink * sink,
|
|
||||||
unsigned int inSampleRate,
|
|
||||||
unsigned int inBitsPerSample,
|
|
||||||
unsigned int inChannel,
|
|
||||||
bool inBigEndian,
|
|
||||||
BitrateMode outBitrateMode,
|
|
||||||
unsigned int outBitrate,
|
|
||||||
unsigned int outSampleRate = 0,
|
|
||||||
unsigned int outChannel = 0 )
|
|
||||||
throw ( Exception )
|
|
||||||
|
|
||||||
: AudioEncoder ( sink,
|
|
||||||
inSampleRate,
|
|
||||||
inBitsPerSample,
|
|
||||||
inChannel,
|
|
||||||
inBigEndian,
|
|
||||||
outBitrateMode,
|
|
||||||
outBitrate,
|
|
||||||
0.0f, // outQuality
|
|
||||||
outSampleRate,
|
|
||||||
outChannel )
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param sink the sink to send mp2 output to
|
|
||||||
* @param as get input sample rate, bits per sample and channels
|
|
||||||
* from this AudioSource.
|
|
||||||
* @param outBitrateMode the bit rate mode of the output.
|
|
||||||
* @param outBitrate bit rate of the output (kbits/sec).
|
|
||||||
* @param outSampleRate sample rate of the output.
|
|
||||||
* If 0, input sample rate is used.
|
|
||||||
* @param outChannel number of channels of the output.
|
|
||||||
* If 0, input channel is used.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
TwoLameLibEncoder ( Sink * sink,
|
|
||||||
const AudioSource * as,
|
|
||||||
BitrateMode outBitrateMode,
|
|
||||||
unsigned int outBitrate,
|
|
||||||
unsigned int outSampleRate = 0,
|
|
||||||
unsigned int outChannel = 0 )
|
|
||||||
throw ( Exception )
|
|
||||||
|
|
||||||
: AudioEncoder ( sink,
|
|
||||||
as,
|
|
||||||
outBitrateMode,
|
|
||||||
outBitrate,
|
|
||||||
0.0f, // outQuality
|
|
||||||
outSampleRate,
|
|
||||||
outChannel )
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor.
|
|
||||||
*
|
|
||||||
* @param encoder the TwoLameLibEncoder to copy.
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
TwoLameLibEncoder ( const TwoLameLibEncoder & encoder )
|
|
||||||
throw ( Exception )
|
|
||||||
: AudioEncoder( encoder )
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~TwoLameLibEncoder ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param encoder the TwoLameLibEncoder to assign this to.
|
|
||||||
* @return a reference to this TwoLameLibEncoder.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual TwoLameLibEncoder &
|
|
||||||
operator= ( const TwoLameLibEncoder & encoder ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &encoder ) {
|
|
||||||
strip();
|
|
||||||
AudioEncoder::operator=( encoder);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the version string of the underlying lame library.
|
|
||||||
*
|
|
||||||
* @return the version string of the underlying lame library.
|
|
||||||
*/
|
|
||||||
inline const char *
|
|
||||||
getLameVersion( void )
|
|
||||||
{
|
|
||||||
return get_twolame_version();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check wether encoding is in progress.
|
|
||||||
*
|
|
||||||
* @return true if encoding is in progress, false otherwise.
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isRunning ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start encoding. This function returns as soon as possible,
|
|
||||||
* with encoding started in the background.
|
|
||||||
*
|
|
||||||
* @return true if encoding has started, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
start ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
return open();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop encoding. Stops the encoding running in the background.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual void
|
|
||||||
stop ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
return close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open an encoding session.
|
|
||||||
*
|
|
||||||
* @return true if opening was successfull, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
open ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the encoding session is open.
|
|
||||||
*
|
|
||||||
* @return true if the encoding session is open, false otherwise.
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isOpen ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return twolame_opts != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the encoder is ready to accept data.
|
|
||||||
*
|
|
||||||
* @param sec the maximum seconds to block.
|
|
||||||
* @param usec micro seconds to block after the full seconds.
|
|
||||||
* @return true if the encoder is ready to accept data,
|
|
||||||
* false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
canWrite ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write data to the encoder.
|
|
||||||
* Buf is expected to be a sequence of big-endian 16 bit values,
|
|
||||||
* with left and right channels interleaved. Len is the number of
|
|
||||||
* bytes, must be a multiple of 4.
|
|
||||||
*
|
|
||||||
* @param buf the data to write.
|
|
||||||
* @param len number of bytes to write from buf.
|
|
||||||
* @return the number of bytes written (may be less than len).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual unsigned int
|
|
||||||
write ( const void * buf,
|
|
||||||
unsigned int len ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush all data that was written to the encoder to the underlying
|
|
||||||
* connection.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
flush ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the encoding session.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
close ( void ) throw ( Exception );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* TWOLAME_LIB_ENCODER_H */
|
|
||||||
|
|
|
@ -1,529 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : Util.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <string.h>
|
|
||||||
#else
|
|
||||||
#error need string.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STDLIB_H
|
|
||||||
#include <stdlib.h>
|
|
||||||
#else
|
|
||||||
#error need stdlib.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_LIMITS_H
|
|
||||||
#include <limits.h>
|
|
||||||
#else
|
|
||||||
#error need limits.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_MATH_H
|
|
||||||
#include <math.h>
|
|
||||||
#else
|
|
||||||
#error need math.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_TIME_H
|
|
||||||
#include <time.h>
|
|
||||||
#else
|
|
||||||
#error need time.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#else
|
|
||||||
#error need unistd.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TIME_H
|
|
||||||
#include <sys/time.h>
|
|
||||||
#else
|
|
||||||
#error need sys/time.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SIGNAL_H
|
|
||||||
#include <signal.h>
|
|
||||||
#else
|
|
||||||
#error need signal.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "Util.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
char
|
|
||||||
Util :: base64Table[] = {
|
|
||||||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
|
|
||||||
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
|
|
||||||
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
|
|
||||||
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Calculate the length of a zero-terminated C string,
|
|
||||||
* w/o the zero-termination
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
Util :: strLen( const char * str ) throw ( Exception )
|
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
if ( !str ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "no str");
|
|
||||||
}
|
|
||||||
|
|
||||||
len = strlen( str);
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Copy the contents of a string into another
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
Util :: strCpy ( char * dest,
|
|
||||||
const char * src ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !dest || !src ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "no src or dest");
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy( dest, src);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Concatenate the contents of a string onto another
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
Util :: strCat ( char * dest,
|
|
||||||
const char * src ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !dest || !src ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "no src or dest");
|
|
||||||
}
|
|
||||||
|
|
||||||
strcat( dest, src);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Duplicate a string by allocating space with new[]
|
|
||||||
* The returned string must be freed with delete[]
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
char *
|
|
||||||
Util :: strDup( const char * str ) throw ( Exception )
|
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
char * s;
|
|
||||||
|
|
||||||
if ( !str ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "no str");
|
|
||||||
}
|
|
||||||
|
|
||||||
len = strlen( str) + 1;
|
|
||||||
s = new char[len];
|
|
||||||
memcpy( s, str, len);
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Convert a string into base64 encoding.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
char *
|
|
||||||
Util :: base64Encode( const char * str ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !str ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "no str");
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * data = str;
|
|
||||||
size_t len = strlen( data);
|
|
||||||
char * out = new char[len * 4 / 3 + 4];
|
|
||||||
char * result = out;
|
|
||||||
unsigned chunk;
|
|
||||||
|
|
||||||
while ( len > 0 ) {
|
|
||||||
chunk = (len > 3) ? 3 : len;
|
|
||||||
*out++ = base64Table[(*data & 0xfc) >> 2];
|
|
||||||
*out++ = base64Table[((*data & 0x03) << 4) | ((*(data+1) & 0xf0) >> 4)];
|
|
||||||
switch ( chunk ) {
|
|
||||||
case 3:
|
|
||||||
*out++ = base64Table[((*(data+1) & 0x0f) << 2) |
|
|
||||||
((*(data+2) & 0xc0) >> 6)];
|
|
||||||
*out++ = base64Table[(*(data+2)) & 0x3f];
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
*out++ = base64Table[((*(data+1) & 0x0f) << 2)];
|
|
||||||
*out++ = '=';
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
*out++ = '=';
|
|
||||||
*out++ = '=';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
data += chunk;
|
|
||||||
len -= chunk;
|
|
||||||
}
|
|
||||||
*out = 0;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Check wether two strings are equal
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
Util :: strEq( const char * str1,
|
|
||||||
const char * str2,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !str1 || !str2 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "no str1 or no str2");
|
|
||||||
}
|
|
||||||
|
|
||||||
return len == 0 ? !strcmp( str1, str2) : !strncmp( str1, str2, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Convert a string to a long integer
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
long int
|
|
||||||
Util :: strToL( const char * str,
|
|
||||||
int base ) throw ( Exception )
|
|
||||||
{
|
|
||||||
long int val;
|
|
||||||
char * s;
|
|
||||||
|
|
||||||
if ( !str ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "no str");
|
|
||||||
}
|
|
||||||
|
|
||||||
val = strtol( str, &s, base);
|
|
||||||
if ( s == str || val == LONG_MIN || val == LONG_MAX ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "number conversion error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Convert a string to a double
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
double
|
|
||||||
Util :: strToD( const char * str ) throw ( Exception )
|
|
||||||
{
|
|
||||||
double val;
|
|
||||||
char * s;
|
|
||||||
|
|
||||||
if ( !str ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "no str");
|
|
||||||
}
|
|
||||||
|
|
||||||
val = strtod( str, &s);
|
|
||||||
if ( s == str || val == HUGE_VAL ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "number conversion error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* add current date to a file name, before the file extension (if any)
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
char *
|
|
||||||
Util :: fileAddDate ( const char * str,
|
|
||||||
const char * format ) throw ( Exception )
|
|
||||||
{
|
|
||||||
unsigned int size;
|
|
||||||
char * s;
|
|
||||||
char * strdate;
|
|
||||||
char * last;
|
|
||||||
time_t now;
|
|
||||||
|
|
||||||
if ( !str ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "no str");
|
|
||||||
}
|
|
||||||
|
|
||||||
strdate = new char[128];
|
|
||||||
now = time(NULL);
|
|
||||||
strftime( strdate, 128, format, localtime (&now));
|
|
||||||
|
|
||||||
// search for the part before the extension of the file name
|
|
||||||
if ( !(last = strrchr( str, '.')) ) {
|
|
||||||
last = (char *) str + strlen( str);
|
|
||||||
}
|
|
||||||
|
|
||||||
size = strlen( str) + strlen( strdate) + 1;
|
|
||||||
s = new char [size];
|
|
||||||
|
|
||||||
memcpy( s, str, strlen (str)-strlen(last));
|
|
||||||
memcpy( s + strlen(str) - strlen(last), strdate, strlen (strdate));
|
|
||||||
memcpy( s + strlen(str) - strlen(last) + strlen(strdate),
|
|
||||||
last,
|
|
||||||
strlen(last));
|
|
||||||
s[size-1] = '\0';
|
|
||||||
|
|
||||||
delete[] strdate;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Convert an unsigned char buffer holding 8 or 16 bit PCM values with
|
|
||||||
* channels interleaved to a short int buffer, still with channels interleaved
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
Util :: conv ( unsigned int bitsPerSample,
|
|
||||||
unsigned char * pcmBuffer,
|
|
||||||
unsigned int lenPcmBuffer,
|
|
||||||
short int * outBuffer,
|
|
||||||
bool isBigEndian ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( bitsPerSample == 8 ) {
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
for ( i = 0, j = 0; i < lenPcmBuffer; ) {
|
|
||||||
outBuffer[j] = pcmBuffer[i++];
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
} else if ( bitsPerSample == 16 ) {
|
|
||||||
|
|
||||||
if ( isBigEndian ) {
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
for ( i = 0, j = 0; i < lenPcmBuffer; ) {
|
|
||||||
short int value;
|
|
||||||
|
|
||||||
value = pcmBuffer[i++] << 8;
|
|
||||||
value |= pcmBuffer[i++];
|
|
||||||
outBuffer[j] = value;
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
for ( i = 0, j = 0; i < lenPcmBuffer; ) {
|
|
||||||
short int value;
|
|
||||||
|
|
||||||
value = pcmBuffer[i++];
|
|
||||||
value |= pcmBuffer[i++] << 8;
|
|
||||||
outBuffer[j] = value;
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"this number of bits per sample not supported",
|
|
||||||
bitsPerSample);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Convert a short buffer holding PCM values with channels interleaved
|
|
||||||
* to one or more float buffers, one for each channel
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
Util :: conv ( short int * shortBuffer,
|
|
||||||
unsigned int lenShortBuffer,
|
|
||||||
float ** floatBuffers,
|
|
||||||
unsigned int channels ) throw ( Exception )
|
|
||||||
{
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
for ( i = 0, j = 0; i < lenShortBuffer; ) {
|
|
||||||
for ( unsigned int c = 0; c < channels; ++c ) {
|
|
||||||
floatBuffers[c][j] = ((float) shortBuffer[i++]) / 32768.f;
|
|
||||||
}
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Convert an unsigned char buffer holding 8 bit PCM values with channels
|
|
||||||
* interleaved to two short int buffers (one for each channel)
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
Util :: conv8 ( unsigned char * pcmBuffer,
|
|
||||||
unsigned int lenPcmBuffer,
|
|
||||||
short int * leftBuffer,
|
|
||||||
short int * rightBuffer,
|
|
||||||
unsigned int channels ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( channels == 1 ) {
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
for ( i = 0, j = 0; i < lenPcmBuffer; ) {
|
|
||||||
unsigned short int value;
|
|
||||||
|
|
||||||
value = pcmBuffer[i++];
|
|
||||||
leftBuffer[j] = (short int) value;
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
} else if ( channels == 2 ) {
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
for ( i = 0, j = 0; i < lenPcmBuffer; ) {
|
|
||||||
unsigned short int value;
|
|
||||||
|
|
||||||
value = pcmBuffer[i++];
|
|
||||||
leftBuffer[j] = (short int) value;
|
|
||||||
value = pcmBuffer[i++];
|
|
||||||
rightBuffer[j] = (short int) value;
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"this number of channels not supported", channels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Convert an unsigned char buffer holding 16 bit PCM values with channels
|
|
||||||
* interleaved to two short int buffers (one for each channel)
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
Util :: conv16 ( unsigned char * pcmBuffer,
|
|
||||||
unsigned int lenPcmBuffer,
|
|
||||||
short int * leftBuffer,
|
|
||||||
short int * rightBuffer,
|
|
||||||
unsigned int channels,
|
|
||||||
bool isBigEndian ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isBigEndian ) {
|
|
||||||
if ( channels == 1 ) {
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
for ( i = 0, j = 0; i < lenPcmBuffer; ) {
|
|
||||||
unsigned short int value;
|
|
||||||
|
|
||||||
value = pcmBuffer[i++] << 8;
|
|
||||||
value |= pcmBuffer[i++];
|
|
||||||
leftBuffer[j] = (short int) value;
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
for ( i = 0, j = 0; i < lenPcmBuffer; ) {
|
|
||||||
unsigned short int value;
|
|
||||||
|
|
||||||
value = pcmBuffer[i++] << 8;
|
|
||||||
value |= pcmBuffer[i++];
|
|
||||||
leftBuffer[j] = (short int) value;
|
|
||||||
value = pcmBuffer[i++] << 8;
|
|
||||||
value |= pcmBuffer[i++];
|
|
||||||
rightBuffer[j] = (short int) value;
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ( channels == 1 ) {
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
for ( i = 0, j = 0; i < lenPcmBuffer; ) {
|
|
||||||
unsigned short int value;
|
|
||||||
|
|
||||||
value = pcmBuffer[i++];
|
|
||||||
value |= pcmBuffer[i++] << 8;
|
|
||||||
leftBuffer[j] = (short int) value;
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
for ( i = 0, j = 0; i < lenPcmBuffer; ) {
|
|
||||||
unsigned short int value;
|
|
||||||
|
|
||||||
value = pcmBuffer[i++];
|
|
||||||
value |= pcmBuffer[i++] << 8;
|
|
||||||
leftBuffer[j] = (short int) value;
|
|
||||||
value = pcmBuffer[i++];
|
|
||||||
value |= pcmBuffer[i++] << 8;
|
|
||||||
rightBuffer[j] = (short int) value;
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Make a thread sleep for a specified amount of time.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
Util :: sleep ( long sec,
|
|
||||||
long nsec)
|
|
||||||
{
|
|
||||||
struct timespec timespec;
|
|
||||||
sigset_t sigset;
|
|
||||||
|
|
||||||
timespec.tv_sec = sec;
|
|
||||||
timespec.tv_nsec = nsec;
|
|
||||||
|
|
||||||
// mask out SIGUSR1, as we're expecting that signal for other reasons
|
|
||||||
sigemptyset(&sigset);
|
|
||||||
sigaddset(&sigset, SIGUSR1);
|
|
||||||
|
|
||||||
pselect( 0, NULL, NULL, NULL, ×pec, &sigset);
|
|
||||||
}
|
|
|
@ -1,332 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : Util.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* #include "Util.h"
|
|
||||||
*
|
|
||||||
* char * str = Util::strDup( otherStr);
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class Util
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper table for base64 encoding.
|
|
||||||
*/
|
|
||||||
static char base64Table[];
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
Util ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
Util ( const Util & e ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
~Util ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @param u the object to assign to this one.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline Util &
|
|
||||||
operator= ( const Util & u ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine a C string's length.
|
|
||||||
*
|
|
||||||
* @param str a zero-terminated C string.
|
|
||||||
* @return length of str
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
static unsigned int
|
|
||||||
strLen ( const char * str ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy a C string into another.
|
|
||||||
*
|
|
||||||
* @param dest place for the copy. Storage size must be at least
|
|
||||||
* Util::strLen(src) + 1 long.
|
|
||||||
* @param src the string to copy.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
strCpy ( char * dest,
|
|
||||||
const char * src ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Concatenate a string to another's end.
|
|
||||||
*
|
|
||||||
* @param dest the string to concatenate to.
|
|
||||||
* Storage size of dest must be at least
|
|
||||||
* Util::strLen(dest) + Util::strLen(src) + 1 long.
|
|
||||||
* @param src the string to concatenate.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
strCat ( char * dest,
|
|
||||||
const char * src ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Duplicate a string by allocating space with new[].
|
|
||||||
* The returned string must be freed with delete[].
|
|
||||||
*
|
|
||||||
* @param str the string to duplicate.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
strDup ( const char * str ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine wether two string are equal.
|
|
||||||
*
|
|
||||||
* @param str1 one of the strings.
|
|
||||||
* @param str2 the other string.
|
|
||||||
* @param len check the first most len characters. if 0, check
|
|
||||||
* the whole string
|
|
||||||
* @return true if the two strings are equal, false othersize.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
strEq ( const char * str1,
|
|
||||||
const char * str2,
|
|
||||||
unsigned int len = 0 ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a string to long.
|
|
||||||
*
|
|
||||||
* @param str the string to convert.
|
|
||||||
* @param base numeric base of number in str.
|
|
||||||
* @return the value of str as a long int
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
static long int
|
|
||||||
strToL ( const char * str,
|
|
||||||
int base = 10 ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a string to double.
|
|
||||||
*
|
|
||||||
* @param str the string to convert.
|
|
||||||
* @return the value of str as a double
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
static double
|
|
||||||
strToD ( const char * str ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add current date to a file name, before the file extension (if any)
|
|
||||||
*
|
|
||||||
* @param str the string to convert (file name).
|
|
||||||
* @return the new string with the date appended before
|
|
||||||
* extension of the file name. the string has to be
|
|
||||||
* deleted with delete[] after it is not needed
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
fileAddDate ( const char * str,
|
|
||||||
const char * format = "[%m-%d-%Y-%H-%M-%S]" )
|
|
||||||
throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a string into base64 encoding.
|
|
||||||
* base64 is described in RFC 2045, section 6.8
|
|
||||||
* The returned string must be freed with delete[].
|
|
||||||
*
|
|
||||||
* @param str the string to convert.
|
|
||||||
* @return the supplied string in base64 encoding.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
base64Encode ( const char * str ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert an unsigned char buffer holding 8 or 16 bit PCM values
|
|
||||||
* with channels interleaved to a short int buffer, still
|
|
||||||
* with channels interleaved.
|
|
||||||
*
|
|
||||||
* @param bitsPerSample the number of bits per sample in the input
|
|
||||||
* @param pcmBuffer the input buffer
|
|
||||||
* @param lenPcmBuffer the number of samples total in pcmBuffer
|
|
||||||
* (e.g. if 2 channel input, this is twice the
|
|
||||||
* number of sound samples)
|
|
||||||
* @param outBuffer the output buffer, must be big enough
|
|
||||||
* @param isBigEndian true if the input is big endian, false otherwise
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
conv ( unsigned int bitsPerSample,
|
|
||||||
unsigned char * pcmBuffer,
|
|
||||||
unsigned int lenPcmBuffer,
|
|
||||||
short int * outBuffer,
|
|
||||||
bool isBigEndian = true ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a short buffer holding PCM values with channels interleaved
|
|
||||||
* to one or more float buffers, one for each channel
|
|
||||||
*
|
|
||||||
* @param shortBuffer the input buffer
|
|
||||||
* @param lenShortBuffer total length of the input buffer
|
|
||||||
* @param floatBuffers an array of float buffers, each
|
|
||||||
* (lenShortBuffer / channels) long
|
|
||||||
* @param channels number of channels to separate the input to
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
conv ( short int * shortBuffer,
|
|
||||||
unsigned int lenShortBuffer,
|
|
||||||
float ** floatBuffers,
|
|
||||||
unsigned int channels ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a char buffer holding 8 bit PCM values to a short buffer
|
|
||||||
*
|
|
||||||
* @param pcmBuffer buffer holding 8 bit PCM audio values,
|
|
||||||
* channels are interleaved
|
|
||||||
* @param lenPcmBuffer length of pcmBuffer
|
|
||||||
* @param leftBuffer put the left channel here (must be big enough)
|
|
||||||
* @param rightBuffer put the right channel here (not touched if mono,
|
|
||||||
* must be big enough)
|
|
||||||
* @param channels number of channels (1 = mono, 2 = stereo)
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
conv8 ( unsigned char * pcmBuffer,
|
|
||||||
unsigned int lenPcmBuffer,
|
|
||||||
short int * leftBuffer,
|
|
||||||
short int * rightBuffer,
|
|
||||||
unsigned int channels ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a char buffer holding 16 bit PCM values to a short buffer
|
|
||||||
*
|
|
||||||
* @param pcmBuffer buffer holding 16 bit PCM audio values,
|
|
||||||
* channels are interleaved
|
|
||||||
* @param lenPcmBuffer length of pcmBuffer
|
|
||||||
* @param leftBuffer put the left channel here (must be big enough)
|
|
||||||
* @param rightBuffer put the right channel here (not touched if mono,
|
|
||||||
* must be big enough)
|
|
||||||
* @param channels number of channels (1 = mono, 2 = stereo)
|
|
||||||
* @param isBigEndian true if input is big endian, false otherwise
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
conv16 ( unsigned char * pcmBuffer,
|
|
||||||
unsigned int lenPcmBuffer,
|
|
||||||
short int * leftBuffer,
|
|
||||||
short int * rightBuffer,
|
|
||||||
unsigned int channels,
|
|
||||||
bool isBigEndian ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make a thread sleep for specified amount of time.
|
|
||||||
* Only the thread which this is called in will sleep.
|
|
||||||
* The SIGUSR1 signal will be blocked during the sleep.
|
|
||||||
*
|
|
||||||
* @param sec the number of seconds to sleep.
|
|
||||||
* @param nsec the number of nano-seconds to sleep.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
sleep( long sec,
|
|
||||||
long nsec);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* UTIL_H */
|
|
||||||
|
|
|
@ -1,417 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : VorbisLibEncoder.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
Copyright notice:
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// compile only if configured for Ogg Vorbis
|
|
||||||
#ifdef HAVE_VORBIS_LIB
|
|
||||||
|
|
||||||
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "VorbisLibEncoder.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Initialize the encoder
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
VorbisLibEncoder :: init ( unsigned int outMaxBitrate )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
this->outMaxBitrate = outMaxBitrate;
|
|
||||||
|
|
||||||
if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 8 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"specified bits per sample not supported",
|
|
||||||
getInBitsPerSample() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( getInChannel() != 1 && getInChannel() != 2 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"unsupported number of channels for the encoder",
|
|
||||||
getInChannel() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( getOutSampleRate() == getInSampleRate() ) {
|
|
||||||
resampleRatio = 1;
|
|
||||||
converter = 0;
|
|
||||||
} else {
|
|
||||||
resampleRatio = ( (double) getOutSampleRate() /
|
|
||||||
(double) getInSampleRate() );
|
|
||||||
|
|
||||||
// Determine if we can use linear interpolation.
|
|
||||||
// The inverse of the ratio must be a power of two for linear mode to
|
|
||||||
// be of sufficient quality.
|
|
||||||
|
|
||||||
bool useLinear = true;
|
|
||||||
double inverse = 1 / resampleRatio;
|
|
||||||
int integer = (int) inverse;
|
|
||||||
|
|
||||||
// Check that the inverse of the ratio is an integer
|
|
||||||
if( integer == inverse ) {
|
|
||||||
while( useLinear && integer ) { // Loop through the bits
|
|
||||||
// If the lowest order bit is not the only one set
|
|
||||||
if( integer & 1 && integer != 1 ) {
|
|
||||||
// Not a power of two; cannot use linear
|
|
||||||
useLinear = false;
|
|
||||||
} else {
|
|
||||||
// Shift all the bits over and try again
|
|
||||||
integer >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
useLinear = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we get here and useLinear is still true, then we have
|
|
||||||
// a power of two.
|
|
||||||
|
|
||||||
// open the aflibConverter in
|
|
||||||
// - high quality
|
|
||||||
// - linear or quadratic (non-linear) based on algorithm
|
|
||||||
// - not filter interpolation
|
|
||||||
converter = new aflibConverter( true, useLinear, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
encoderOpen = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Open an encoding session
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
VorbisLibEncoder :: open ( void )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// open the underlying sink
|
|
||||||
if ( !getSink()->open() ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"vorbis lib opening underlying sink error");
|
|
||||||
}
|
|
||||||
|
|
||||||
vorbis_info_init( &vorbisInfo);
|
|
||||||
|
|
||||||
switch ( getOutBitrateMode() ) {
|
|
||||||
|
|
||||||
case cbr: {
|
|
||||||
int maxBitrate = getOutMaxBitrate() * 1000;
|
|
||||||
if ( !maxBitrate ) {
|
|
||||||
maxBitrate = -1;
|
|
||||||
}
|
|
||||||
if ( (ret = vorbis_encode_init( &vorbisInfo,
|
|
||||||
getOutChannel(),
|
|
||||||
getOutSampleRate(),
|
|
||||||
maxBitrate,
|
|
||||||
getOutBitrate() * 1000,
|
|
||||||
-1)) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"vorbis encode init error", ret);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case abr:
|
|
||||||
/* set non-managed VBR around the average bitrate */
|
|
||||||
ret = vorbis_encode_setup_managed( &vorbisInfo,
|
|
||||||
getOutChannel(),
|
|
||||||
getOutSampleRate(),
|
|
||||||
-1,
|
|
||||||
getOutBitrate() * 1000,
|
|
||||||
-1 )
|
|
||||||
|| vorbis_encode_ctl( &vorbisInfo, OV_ECTL_RATEMANAGE_SET, NULL)
|
|
||||||
|| vorbis_encode_setup_init( &vorbisInfo);
|
|
||||||
if ( ret ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"vorbis encode init error", ret);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case vbr:
|
|
||||||
if ( (ret = vorbis_encode_init_vbr( &vorbisInfo,
|
|
||||||
getOutChannel(),
|
|
||||||
getOutSampleRate(),
|
|
||||||
getOutQuality() )) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"vorbis encode init error", ret);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (ret = vorbis_analysis_init( &vorbisDspState, &vorbisInfo)) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "vorbis analysis init error", ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (ret = vorbis_block_init( &vorbisDspState, &vorbisBlock)) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "vorbis block init error", ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (ret = ogg_stream_init( &oggStreamState, 0)) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "ogg stream init error", ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create an empty vorbis_comment structure
|
|
||||||
vorbis_comment_init( &vorbisComment);
|
|
||||||
/* FIXME: removed title metadata when the sink type was changed from
|
|
||||||
* CastSink to the more generic Sink.
|
|
||||||
* make sure to add metadata somehow
|
|
||||||
// Add comment to vorbis headers to show title in players
|
|
||||||
// stupid cast to (char*) because of stupid vorbis API
|
|
||||||
if ( getSink()->getName() ) {
|
|
||||||
vorbis_comment_add_tag(&vorbisComment,
|
|
||||||
"TITLE",
|
|
||||||
(char*) getSink()->getName());
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// create the vorbis stream headers and send them to the underlying sink
|
|
||||||
ogg_packet header;
|
|
||||||
ogg_packet commentHeader;
|
|
||||||
ogg_packet codeHeader;
|
|
||||||
|
|
||||||
if ( (ret = vorbis_analysis_headerout( &vorbisDspState,
|
|
||||||
&vorbisComment,
|
|
||||||
&header,
|
|
||||||
&commentHeader,
|
|
||||||
&codeHeader )) ) {
|
|
||||||
throw Exception( __FILE__, __LINE__, "vorbis header init error", ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
ogg_stream_packetin( &oggStreamState, &header);
|
|
||||||
ogg_stream_packetin( &oggStreamState, &commentHeader);
|
|
||||||
ogg_stream_packetin( &oggStreamState, &codeHeader);
|
|
||||||
|
|
||||||
ogg_page oggPage;
|
|
||||||
while ( ogg_stream_flush( &oggStreamState, &oggPage) ) {
|
|
||||||
getSink()->write( oggPage.header, oggPage.header_len);
|
|
||||||
getSink()->write( oggPage.body, oggPage.body_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
vorbis_comment_clear( &vorbisComment );
|
|
||||||
|
|
||||||
// initialize the resampling coverter if needed
|
|
||||||
if ( converter ) {
|
|
||||||
converter->initialize( resampleRatio, getInChannel());
|
|
||||||
}
|
|
||||||
|
|
||||||
encoderOpen = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Write data to the encoder
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
VorbisLibEncoder :: write ( const void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() || len == 0 ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int channels = getInChannel();
|
|
||||||
unsigned int bitsPerSample = getInBitsPerSample();
|
|
||||||
unsigned int sampleSize = (bitsPerSample / 8) * channels;
|
|
||||||
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if ( getInChannel() == 2 && getOutChannel() == 1 ) {
|
|
||||||
for ( i = 0; i < len/sampleSize; i++) {
|
|
||||||
if ( bitsPerSample == 8 ) {
|
|
||||||
char * buf8 = (char *) buf;
|
|
||||||
unsigned int ix = sampleSize * i;
|
|
||||||
unsigned int iix = ix;
|
|
||||||
buf8[i] = (buf8[ix] + buf8[++iix]) / 2;
|
|
||||||
}
|
|
||||||
if ( bitsPerSample == 16 ) {
|
|
||||||
short * buf16 = (short *) buf;
|
|
||||||
unsigned int ix = (bitsPerSample >> 3) * i;
|
|
||||||
unsigned int iix = ix;
|
|
||||||
buf16[i] = (buf16[ix] + buf16[++iix]) / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
len >>= 1;
|
|
||||||
channels = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sampleSize = (bitsPerSample / 8) * channels;
|
|
||||||
unsigned char * b = (unsigned char*) buf;
|
|
||||||
unsigned int processed = len - (len % sampleSize);
|
|
||||||
unsigned int nSamples = processed / sampleSize;
|
|
||||||
float ** vorbisBuffer;
|
|
||||||
|
|
||||||
|
|
||||||
// convert the byte-based raw input into a short buffer
|
|
||||||
// with channels still interleaved
|
|
||||||
unsigned int totalSamples = nSamples * channels;
|
|
||||||
short int * shortBuffer = new short int[totalSamples];
|
|
||||||
|
|
||||||
|
|
||||||
Util::conv( bitsPerSample, b, processed, shortBuffer, isInBigEndian());
|
|
||||||
|
|
||||||
if ( converter ) {
|
|
||||||
// resample if needed
|
|
||||||
int inCount = nSamples;
|
|
||||||
int outCount = (int) (inCount * resampleRatio);
|
|
||||||
short int * resampledBuffer = new short int[outCount * channels];
|
|
||||||
int converted;
|
|
||||||
|
|
||||||
converted = converter->resample( inCount,
|
|
||||||
outCount,
|
|
||||||
shortBuffer,
|
|
||||||
resampledBuffer );
|
|
||||||
|
|
||||||
vorbisBuffer = vorbis_analysis_buffer( &vorbisDspState,
|
|
||||||
converted);
|
|
||||||
Util::conv( resampledBuffer,
|
|
||||||
converted * channels,
|
|
||||||
vorbisBuffer,
|
|
||||||
channels);
|
|
||||||
delete[] resampledBuffer;
|
|
||||||
|
|
||||||
vorbis_analysis_wrote( &vorbisDspState, converted);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
vorbisBuffer = vorbis_analysis_buffer( &vorbisDspState, nSamples);
|
|
||||||
Util::conv( shortBuffer, totalSamples, vorbisBuffer, channels);
|
|
||||||
vorbis_analysis_wrote( &vorbisDspState, nSamples);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] shortBuffer;
|
|
||||||
vorbisBlocksOut();
|
|
||||||
|
|
||||||
return processed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Flush the data from the encoder
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
VorbisLibEncoder :: flush ( void )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vorbis_analysis_wrote( &vorbisDspState, 0);
|
|
||||||
vorbisBlocksOut();
|
|
||||||
getSink()->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 = getSink()->write(oggPage.header, oggPage.header_len);
|
|
||||||
written += getSink()->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;
|
|
||||||
|
|
||||||
getSink()->close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // HAVE_VORBIS_LIB
|
|
||||||
|
|
|
@ -1,435 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : VorbisLibEncoder.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <vorbis/vorbisenc.h>
|
|
||||||
#else
|
|
||||||
#error configure for Ogg Vorbis
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "Ref.h"
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "Reporter.h"
|
|
||||||
#include "AudioEncoder.h"
|
|
||||||
#include "CastSink.h"
|
|
||||||
#include "aflibConverter.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class representing the ogg vorbis encoder linked as a shared object or
|
|
||||||
* as a static library.
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
class VorbisLibEncoder : public AudioEncoder, public virtual Reporter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Value indicating if the encoding process is going on
|
|
||||||
*/
|
|
||||||
bool encoderOpen;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ogg Vorbis library global info
|
|
||||||
*/
|
|
||||||
vorbis_info vorbisInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ogg Vorbis library global DSP state
|
|
||||||
*/
|
|
||||||
vorbis_dsp_state vorbisDspState;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ogg Vorbis library global block
|
|
||||||
*/
|
|
||||||
vorbis_block vorbisBlock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ogg Vorbis library global comment
|
|
||||||
*/
|
|
||||||
vorbis_comment vorbisComment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ogg library global stream state
|
|
||||||
*/
|
|
||||||
ogg_stream_state oggStreamState;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maximum bitrate of the output in kbits/sec. If 0, don't care.
|
|
||||||
*/
|
|
||||||
unsigned int outMaxBitrate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resample ratio
|
|
||||||
*/
|
|
||||||
double resampleRatio;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* aflibConverter object for possible resampling
|
|
||||||
*/
|
|
||||||
aflibConverter * converter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object.
|
|
||||||
*
|
|
||||||
* @param the maximum bit rate
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
init ( unsigned int outMaxBitrate ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-initialize the object.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline void
|
|
||||||
strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( converter ) {
|
|
||||||
delete converter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send pending Vorbis blocks to the underlying stream
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
vorbisBlocksOut( void ) throw ( Exception );
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
VorbisLibEncoder ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param sink the sink to send encoded output to
|
|
||||||
* @param inSampleRate sample rate of the input.
|
|
||||||
* @param inBitsPerSample number of bits per sample of the input.
|
|
||||||
* @param inChannel number of channels of the input.
|
|
||||||
* @param inBigEndian shows if the input is big or little endian
|
|
||||||
* @param outBitrateMode the bit rate mode of the output.
|
|
||||||
* @param outBitrate bit rate of the output (kbits/sec).
|
|
||||||
* @param outQuality the quality of the stream.
|
|
||||||
* @param outSampleRate sample rate of the output.
|
|
||||||
* If 0, inSampleRate is used.
|
|
||||||
* @param outMaxBitrate maximum output bitrate.
|
|
||||||
* 0 if not used.
|
|
||||||
* @param outChannel number of channels of the output.
|
|
||||||
* If 0, inChannel is used.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
VorbisLibEncoder ( CastSink * sink,
|
|
||||||
unsigned int inSampleRate,
|
|
||||||
unsigned int inBitsPerSample,
|
|
||||||
unsigned int inChannel,
|
|
||||||
bool inBigEndian,
|
|
||||||
BitrateMode outBitrateMode,
|
|
||||||
unsigned int outBitrate,
|
|
||||||
double outQuality,
|
|
||||||
unsigned int outSampleRate = 0,
|
|
||||||
unsigned int outChannel = 0,
|
|
||||||
unsigned int outMaxBitrate = 0 )
|
|
||||||
throw ( Exception )
|
|
||||||
|
|
||||||
: AudioEncoder ( sink,
|
|
||||||
inSampleRate,
|
|
||||||
inBitsPerSample,
|
|
||||||
inChannel,
|
|
||||||
inBigEndian,
|
|
||||||
outBitrateMode,
|
|
||||||
outBitrate,
|
|
||||||
outQuality,
|
|
||||||
outSampleRate,
|
|
||||||
outChannel )
|
|
||||||
{
|
|
||||||
init( outMaxBitrate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param sink the sink to send encoded output to
|
|
||||||
* @param as get input sample rate, bits per sample and channels
|
|
||||||
* from this AudioSource.
|
|
||||||
* @param outBitrateMode the bit rate mode of the output.
|
|
||||||
* @param outBitrate bit rate of the output (kbits/sec).
|
|
||||||
* @param outQuality the quality of the stream.
|
|
||||||
* @param outSampleRate sample rate of the output.
|
|
||||||
* If 0, input sample rate is used.
|
|
||||||
* @param outMaxBitrate maximum output bitrate.
|
|
||||||
* 0 if not used.
|
|
||||||
* @param outChannel number of channels of the output.
|
|
||||||
* If 0, input channel is used.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
VorbisLibEncoder ( CastSink * sink,
|
|
||||||
const AudioSource * as,
|
|
||||||
BitrateMode outBitrateMode,
|
|
||||||
unsigned int outBitrate,
|
|
||||||
double outQuality,
|
|
||||||
unsigned int outSampleRate = 0,
|
|
||||||
unsigned int outChannel = 0,
|
|
||||||
unsigned int outMaxBitrate = 0 )
|
|
||||||
throw ( Exception )
|
|
||||||
|
|
||||||
: AudioEncoder ( sink,
|
|
||||||
as,
|
|
||||||
outBitrateMode,
|
|
||||||
outBitrate,
|
|
||||||
outQuality,
|
|
||||||
outSampleRate,
|
|
||||||
outChannel )
|
|
||||||
{
|
|
||||||
init( outMaxBitrate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor.
|
|
||||||
*
|
|
||||||
* @param encoder the VorbisLibEncoder to copy.
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
VorbisLibEncoder ( const VorbisLibEncoder & encoder )
|
|
||||||
throw ( Exception )
|
|
||||||
: AudioEncoder( encoder )
|
|
||||||
{
|
|
||||||
if( encoder.isOpen() ) {
|
|
||||||
throw Exception(__FILE__, __LINE__, "don't copy open encoders");
|
|
||||||
}
|
|
||||||
init( encoder.getOutMaxBitrate() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~VorbisLibEncoder ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param encoder the VorbisLibEncoder to assign this to.
|
|
||||||
* @return a reference to this VorbisLibEncoder.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual VorbisLibEncoder &
|
|
||||||
operator= ( const VorbisLibEncoder & encoder ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if( encoder.isOpen() ) {
|
|
||||||
throw Exception(__FILE__, __LINE__, "don't copy open encoders");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( this != &encoder ) {
|
|
||||||
strip();
|
|
||||||
AudioEncoder::operator=( encoder);
|
|
||||||
init( encoder.getOutMaxBitrate() );
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the maximum bit rate of the output in kbits/sec,
|
|
||||||
* for fixed / average bitrate encodings.
|
|
||||||
*
|
|
||||||
* @return the maximum bit rate of the output, or 0 if not set.
|
|
||||||
*/
|
|
||||||
inline unsigned int
|
|
||||||
getOutMaxBitrate ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return outMaxBitrate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check wether encoding is in progress.
|
|
||||||
*
|
|
||||||
* @return true if encoding is in progress, false otherwise.
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isRunning ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start encoding. This function returns as soon as possible,
|
|
||||||
* with encoding started in the background.
|
|
||||||
*
|
|
||||||
* @return true if encoding has started, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
start ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
return open();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop encoding. Stops the encoding running in the background.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual void
|
|
||||||
stop ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
return close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open an encoding session.
|
|
||||||
*
|
|
||||||
* @return true if opening was successfull, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
open ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the encoding session is open.
|
|
||||||
*
|
|
||||||
* @return true if the encoding session is open, false otherwise.
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isOpen ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return encoderOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the encoder is ready to accept data.
|
|
||||||
*
|
|
||||||
* @param sec the maximum seconds to block.
|
|
||||||
* @param usec micro seconds to block after the full seconds.
|
|
||||||
* @return true if the encoder is ready to accept data,
|
|
||||||
* false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
canWrite ( unsigned int sec,
|
|
||||||
unsigned int usec ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write data to the encoder.
|
|
||||||
* Buf is expected to be a sequence of big-endian 16 bit values,
|
|
||||||
* with left and right channels interleaved. Len is the number of
|
|
||||||
* bytes, must be a multiple of 4.
|
|
||||||
*
|
|
||||||
* @param buf the data to write.
|
|
||||||
* @param len number of bytes to write from buf.
|
|
||||||
* @return the number of bytes written (may be less than len).
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual unsigned int
|
|
||||||
write ( const void * buf,
|
|
||||||
unsigned int len ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush all data that was written to the encoder to the underlying
|
|
||||||
* connection.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
flush ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the encoding session.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual void
|
|
||||||
close ( void ) throw ( Exception );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================= external data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ====================================================== function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* VORBIS_LIB_ENCODER_H */
|
|
||||||
|
|
|
@ -1,301 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2005 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : aacPlusEncoder.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 aacplus support configured in
|
|
||||||
#ifdef HAVE_AACPLUS_LIB
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "aacPlusEncoder.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Open an encoding session
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
bool
|
|
||||||
aacPlusEncoder :: open ( void )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// open the underlying sink
|
|
||||||
if ( !sink->open() ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"aacplus lib opening underlying sink error");
|
|
||||||
}
|
|
||||||
|
|
||||||
reportEvent(1, "Using aacplus codec version", "720 3gpp");
|
|
||||||
|
|
||||||
bitrate = getOutBitrate() * 1000;
|
|
||||||
bandwidth = 0;
|
|
||||||
useParametricStereo = 0;
|
|
||||||
numAncDataBytes=0;
|
|
||||||
coreWriteOffset = 0;
|
|
||||||
envReadOffset = 0;
|
|
||||||
writeOffset = INPUT_DELAY*MAX_CHANNELS;
|
|
||||||
writtenSamples = 0;
|
|
||||||
aacEnc = NULL;
|
|
||||||
hEnvEnc=NULL;
|
|
||||||
|
|
||||||
/* set up basic parameters for aacPlus codec */
|
|
||||||
AacInitDefaultConfig(&config);
|
|
||||||
nChannelsAAC = nChannelsSBR = getOutChannel();
|
|
||||||
|
|
||||||
if ( (getInChannel() == 2) && (bitrate >= 16000) && (bitrate < 44001) ) {
|
|
||||||
useParametricStereo = 1;
|
|
||||||
nChannelsAAC = 1;
|
|
||||||
nChannelsSBR = 2;
|
|
||||||
|
|
||||||
reportEvent(10, "use Parametric Stereo");
|
|
||||||
|
|
||||||
envReadOffset = (MAX_DS_FILTER_DELAY + INPUT_DELAY)*MAX_CHANNELS;
|
|
||||||
coreWriteOffset = CORE_INPUT_OFFSET_PS;
|
|
||||||
writeOffset = envReadOffset;
|
|
||||||
} else {
|
|
||||||
/* set up 2:1 downsampling */
|
|
||||||
InitIIR21_Resampler(&(IIR21_reSampler[0]));
|
|
||||||
InitIIR21_Resampler(&(IIR21_reSampler[1]));
|
|
||||||
|
|
||||||
if(IIR21_reSampler[0].delay > MAX_DS_FILTER_DELAY)
|
|
||||||
throw Exception(__FILE__, __LINE__, "IIR21 resampler delay is bigger then MAX_DS_FILTER_DELAY");
|
|
||||||
writeOffset += IIR21_reSampler[0].delay*MAX_CHANNELS;
|
|
||||||
}
|
|
||||||
|
|
||||||
sampleRateAAC = getInSampleRate();
|
|
||||||
config.bitRate = bitrate;
|
|
||||||
config.nChannelsIn=getInChannel();
|
|
||||||
config.nChannelsOut=nChannelsAAC;
|
|
||||||
config.bandWidth=bandwidth;
|
|
||||||
|
|
||||||
/* set up SBR configuration */
|
|
||||||
if(!IsSbrSettingAvail(bitrate, nChannelsAAC, sampleRateAAC, &sampleRateAAC))
|
|
||||||
throw Exception(__FILE__, __LINE__, "No valid SBR configuration found");
|
|
||||||
|
|
||||||
InitializeSbrDefaults (&sbrConfig);
|
|
||||||
sbrConfig.usePs = useParametricStereo;
|
|
||||||
|
|
||||||
AdjustSbrSettings( &sbrConfig,
|
|
||||||
bitrate,
|
|
||||||
nChannelsAAC,
|
|
||||||
sampleRateAAC,
|
|
||||||
AACENC_TRANS_FAC,
|
|
||||||
24000);
|
|
||||||
|
|
||||||
EnvOpen( &hEnvEnc,
|
|
||||||
inBuf + coreWriteOffset,
|
|
||||||
&sbrConfig,
|
|
||||||
&config.bandWidth);
|
|
||||||
|
|
||||||
/* set up AAC encoder, now that samling rate is known */
|
|
||||||
config.sampleRate = sampleRateAAC;
|
|
||||||
if (AacEncOpen(&aacEnc, config) != 0){
|
|
||||||
AacEncClose(aacEnc);
|
|
||||||
throw Exception(__FILE__, __LINE__, "Initialisation of AAC failed !");
|
|
||||||
}
|
|
||||||
|
|
||||||
init_plans();
|
|
||||||
|
|
||||||
/* create the ADTS header */
|
|
||||||
adts_hdr(outBuf, &config);
|
|
||||||
|
|
||||||
inSamples = AACENC_BLOCKSIZE * getInChannel() * 2;
|
|
||||||
|
|
||||||
aacplusOpen = true;
|
|
||||||
reportEvent(10, "bitrate=", bitrate);
|
|
||||||
reportEvent(10, "nChannelsIn", getInChannel());
|
|
||||||
reportEvent(10, "nChannelsOut", getOutChannel());
|
|
||||||
reportEvent(10, "nChannelsSBR", nChannelsSBR);
|
|
||||||
reportEvent(10, "nChannelsAAC", nChannelsAAC);
|
|
||||||
reportEvent(10, "sampleRateAAC", sampleRateAAC);
|
|
||||||
reportEvent(10, "inSamples", inSamples);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Write data to the encoder
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
unsigned int
|
|
||||||
aacPlusEncoder :: write ( const void * buf,
|
|
||||||
unsigned int len ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() || len == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int channels = getInChannel();
|
|
||||||
unsigned int bitsPerSample = getInBitsPerSample();
|
|
||||||
unsigned int sampleSize = (bitsPerSample / 8) * channels;
|
|
||||||
unsigned int processed = len - (len % sampleSize);
|
|
||||||
unsigned int nSamples = processed / sampleSize;
|
|
||||||
unsigned int samples = (unsigned int) nSamples * channels;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int i;
|
|
||||||
int ch, outSamples, numOutBytes;
|
|
||||||
|
|
||||||
|
|
||||||
reportEvent(10, "converting short to float");
|
|
||||||
short *TimeDataPcm = (short *) buf;
|
|
||||||
|
|
||||||
if(channels == 2) {
|
|
||||||
for (i=0; i<samples; i++)
|
|
||||||
inBuf[i+writeOffset+writtenSamples] = (float) TimeDataPcm[i];
|
|
||||||
} else {
|
|
||||||
/* using only left channel buffer for mono encoder */
|
|
||||||
for (i=0; i<samples; i++)
|
|
||||||
inBuf[writeOffset+2*writtenSamples+2*i] = (float) TimeDataPcm[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
writtenSamples+=samples;
|
|
||||||
reportEvent(10, "writtenSamples", writtenSamples);
|
|
||||||
|
|
||||||
if (writtenSamples < inSamples)
|
|
||||||
return samples;
|
|
||||||
|
|
||||||
/* encode one SBR frame */
|
|
||||||
reportEvent(10, "encode one SBR frame");
|
|
||||||
EnvEncodeFrame( hEnvEnc,
|
|
||||||
inBuf + envReadOffset,
|
|
||||||
inBuf + coreWriteOffset,
|
|
||||||
MAX_CHANNELS,
|
|
||||||
&numAncDataBytes,
|
|
||||||
ancDataBytes);
|
|
||||||
|
|
||||||
reportEvent(10, "numAncDataBytes=", numAncDataBytes);
|
|
||||||
|
|
||||||
/* 2:1 downsampling for AAC core */
|
|
||||||
if (!useParametricStereo) {
|
|
||||||
reportEvent(10, "2:1 downsampling for AAC core");
|
|
||||||
for( ch=0; ch<nChannelsAAC; ch++ )
|
|
||||||
IIR21_Downsample( &(IIR21_reSampler[ch]),
|
|
||||||
inBuf + writeOffset+ch,
|
|
||||||
writtenSamples/channels,
|
|
||||||
MAX_CHANNELS,
|
|
||||||
inBuf+ch,
|
|
||||||
&outSamples,
|
|
||||||
MAX_CHANNELS);
|
|
||||||
|
|
||||||
reportEvent(10, "outSamples=", outSamples);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* encode one AAC frame */
|
|
||||||
reportEvent(10, "encode one AAC frame");
|
|
||||||
AacEncEncode( aacEnc,
|
|
||||||
inBuf,
|
|
||||||
useParametricStereo ? 1 : MAX_CHANNELS, /* stride (step) */
|
|
||||||
ancDataBytes,
|
|
||||||
&numAncDataBytes,
|
|
||||||
(unsigned *) (outBuf+ADTS_HEADER_SIZE),
|
|
||||||
&numOutBytes);
|
|
||||||
if (useParametricStereo) {
|
|
||||||
memcpy( inBuf,inBuf+AACENC_BLOCKSIZE,CORE_INPUT_OFFSET_PS*sizeof(float));
|
|
||||||
} else {
|
|
||||||
memmove( inBuf,inBuf+AACENC_BLOCKSIZE*2*MAX_CHANNELS,writeOffset*sizeof(float));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write one frame of encoded audio */
|
|
||||||
if (numOutBytes) {
|
|
||||||
reportEvent(10, "Write one frame of encoded audio:", numOutBytes+ADTS_HEADER_SIZE);
|
|
||||||
adts_hdr_up(outBuf, numOutBytes);
|
|
||||||
sink->write(outBuf, numOutBytes+ADTS_HEADER_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
writtenSamples=0;
|
|
||||||
|
|
||||||
return samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Flush the data from the encoder
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
aacPlusEncoder :: flush ( void )
|
|
||||||
throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( !isOpen() ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sink->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Close the encoding session
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
aacPlusEncoder :: close ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
flush();
|
|
||||||
|
|
||||||
destroy_plans();
|
|
||||||
AacEncClose(aacEnc);
|
|
||||||
if (hEnvEnc) {
|
|
||||||
EnvClose(hEnvEnc);
|
|
||||||
}
|
|
||||||
|
|
||||||
aacplusOpen = false;
|
|
||||||
|
|
||||||
sink->close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // HAVE_AACPLUS_LIB
|
|
|
@ -1,474 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : aacPlusEncoder.h
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 AACP_ENCODER_H
|
|
||||||
#define AACP_ENCODER_H
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#error This is a C++ include file
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================ include files */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_AACPLUS_LIB
|
|
||||||
extern "C" {
|
|
||||||
#include <libaacplus/cfftn.h>
|
|
||||||
#include <libaacplus/FloatFR.h>
|
|
||||||
#include <libaacplus/aacenc.h>
|
|
||||||
#include <libaacplus/resampler.h>
|
|
||||||
|
|
||||||
#include <libaacplus/adts.h>
|
|
||||||
|
|
||||||
#include <libaacplus/sbr_main.h>
|
|
||||||
#include <libaacplus/aac_ram.h>
|
|
||||||
#include <libaacplus/aac_rom.h>
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#error configure with aacplus
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include "Ref.h"
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "Reporter.h"
|
|
||||||
#include "AudioEncoder.h"
|
|
||||||
#include "Sink.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================ constants */
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================================== macros */
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================== data types */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class representing aacplus AAC+ encoder.
|
|
||||||
*
|
|
||||||
* @author $Author$
|
|
||||||
* @version $Revision$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define CORE_DELAY (1600)
|
|
||||||
#define INPUT_DELAY ((CORE_DELAY)*2 +6*64-2048+1) /* ((1600 (core codec)*2 (multi rate) + 6*64 (sbr dec delay) - 2048 (sbr enc delay) + magic*/
|
|
||||||
#define MAX_DS_FILTER_DELAY 16 /* the additional max resampler filter delay (source fs)*/
|
|
||||||
|
|
||||||
#define CORE_INPUT_OFFSET_PS (0) /* (96-64) makes AAC still some 64 core samples too early wrt SBR ... maybe -32 would be even more correct, but 1024-32 would need additional SBR bitstream delay by one frame */
|
|
||||||
|
|
||||||
class aacPlusEncoder : public AudioEncoder, public virtual Reporter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* A flag to indicate if the encoding session is open.
|
|
||||||
*/
|
|
||||||
bool aacplusOpen;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Sink to dump aac+ data to
|
|
||||||
*/
|
|
||||||
Ref<Sink> sink;
|
|
||||||
|
|
||||||
float inBuf[(AACENC_BLOCKSIZE*2 + MAX_DS_FILTER_DELAY + INPUT_DELAY)*MAX_CHANNELS];
|
|
||||||
char outBuf[(6144/8)*MAX_CHANNELS+ADTS_HEADER_SIZE];
|
|
||||||
IIR21_RESAMPLER IIR21_reSampler[MAX_CHANNELS];
|
|
||||||
|
|
||||||
AACENC_CONFIG config;
|
|
||||||
|
|
||||||
int nChannelsAAC, nChannelsSBR;
|
|
||||||
unsigned int sampleRateAAC;
|
|
||||||
|
|
||||||
int bitrate;
|
|
||||||
int bandwidth;
|
|
||||||
|
|
||||||
unsigned int numAncDataBytes;
|
|
||||||
unsigned char ancDataBytes[MAX_PAYLOAD_SIZE];
|
|
||||||
|
|
||||||
bool useParametricStereo;
|
|
||||||
int coreWriteOffset;
|
|
||||||
int envReadOffset;
|
|
||||||
int writeOffset;
|
|
||||||
struct AAC_ENCODER *aacEnc;
|
|
||||||
unsigned int inSamples;
|
|
||||||
unsigned int writtenSamples;
|
|
||||||
|
|
||||||
HANDLE_SBR_ENCODER hEnvEnc;
|
|
||||||
sbrConfiguration sbrConfig;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the object.
|
|
||||||
*
|
|
||||||
* @param sink the sink to send mp3 output to
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline void
|
|
||||||
init ( Sink * sink) throw (Exception)
|
|
||||||
{
|
|
||||||
this->aacplusOpen = false;
|
|
||||||
this->sink = sink;
|
|
||||||
|
|
||||||
/* TODO: if we have float as input, we don't need conversion */
|
|
||||||
if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 32 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"specified bits per sample not supported",
|
|
||||||
getInBitsPerSample() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( getInChannel() > 2 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"unsupported number of input channels for the encoder",
|
|
||||||
getInChannel() );
|
|
||||||
}
|
|
||||||
if ( getOutChannel() > 2 ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"unsupported number of output channels for the encoder",
|
|
||||||
getOutChannel() );
|
|
||||||
}
|
|
||||||
/* TODO: this will be neede when we implement mono aac+ encoding */
|
|
||||||
if ( getInChannel() != getOutChannel() ) {
|
|
||||||
throw Exception( __FILE__, __LINE__,
|
|
||||||
"input channels and output channels do not match");
|
|
||||||
}
|
|
||||||
|
|
||||||
bitrate = getOutBitrate() * 1000;
|
|
||||||
bandwidth = 0;
|
|
||||||
useParametricStereo = 0;
|
|
||||||
numAncDataBytes=0;
|
|
||||||
coreWriteOffset = 0;
|
|
||||||
envReadOffset = 0;
|
|
||||||
writeOffset = INPUT_DELAY*MAX_CHANNELS;
|
|
||||||
writtenSamples = 0;
|
|
||||||
aacEnc = NULL;
|
|
||||||
hEnvEnc=NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-initialize the object.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline void
|
|
||||||
strip ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default constructor. Always throws an Exception.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
aacPlusEncoder ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
throw Exception( __FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param sink the sink to send mp3 output to
|
|
||||||
* @param inSampleRate sample rate of the input.
|
|
||||||
* @param inBitsPerSample number of bits per sample of the input.
|
|
||||||
* @param inChannel number of channels of the input.
|
|
||||||
* @param inBigEndian shows if the input is big or little endian
|
|
||||||
* @param outBitrateMode the bit rate mode of the output.
|
|
||||||
* @param outBitrate bit rate of the output (kbits/sec).
|
|
||||||
* @param outQuality the quality of the stream.
|
|
||||||
* @param outSampleRate sample rate of the output.
|
|
||||||
* If 0, inSampleRate is used.
|
|
||||||
* @param outChannel number of channels of the output.
|
|
||||||
* If 0, inChannel is used.
|
|
||||||
* @param lowpass frequency threshold for the lowpass filter.
|
|
||||||
* Input above this frequency is cut.
|
|
||||||
* If 0, aacplus's default values are used,
|
|
||||||
* which depends on the out sample rate.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
aacPlusEncoder ( Sink * sink,
|
|
||||||
unsigned int inSampleRate,
|
|
||||||
unsigned int inBitsPerSample,
|
|
||||||
unsigned int inChannel,
|
|
||||||
bool inBigEndian,
|
|
||||||
BitrateMode outBitrateMode,
|
|
||||||
unsigned int outBitrate,
|
|
||||||
double outQuality,
|
|
||||||
unsigned int outSampleRate = 0,
|
|
||||||
unsigned int outChannel = 0,
|
|
||||||
int lowpass = 0)
|
|
||||||
throw ( Exception )
|
|
||||||
|
|
||||||
: AudioEncoder ( sink,
|
|
||||||
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.
|
|
||||||
* @param lowpass frequency threshold for the lowpass filter.
|
|
||||||
* Input above this frequency is cut.
|
|
||||||
* If 0, aacplus's default values are used,
|
|
||||||
* which depends on the out sample rate.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
aacPlusEncoder ( Sink * sink,
|
|
||||||
const AudioSource * as,
|
|
||||||
BitrateMode outBitrateMode,
|
|
||||||
unsigned int outBitrate,
|
|
||||||
double outQuality,
|
|
||||||
unsigned int outSampleRate = 0,
|
|
||||||
unsigned int outChannel = 0,
|
|
||||||
int lowpass = 0)
|
|
||||||
throw ( Exception )
|
|
||||||
|
|
||||||
: AudioEncoder ( sink,
|
|
||||||
as,
|
|
||||||
outBitrateMode,
|
|
||||||
outBitrate,
|
|
||||||
outQuality,
|
|
||||||
outSampleRate,
|
|
||||||
outChannel )
|
|
||||||
{
|
|
||||||
init( sink);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor.
|
|
||||||
*
|
|
||||||
* @param encoder the aacPlusEncoder to copy.
|
|
||||||
*/
|
|
||||||
inline
|
|
||||||
aacPlusEncoder ( const aacPlusEncoder & encoder )
|
|
||||||
throw ( Exception )
|
|
||||||
: AudioEncoder( encoder )
|
|
||||||
{
|
|
||||||
init( encoder.sink.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual
|
|
||||||
~aacPlusEncoder ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( isOpen() ) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
strip();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator.
|
|
||||||
*
|
|
||||||
* @param encoder the aacPlusEncoder to assign this to.
|
|
||||||
* @return a reference to this aacPlusEncoder.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual aacPlusEncoder &
|
|
||||||
operator= ( const aacPlusEncoder & encoder ) throw ( Exception )
|
|
||||||
{
|
|
||||||
if ( this != &encoder ) {
|
|
||||||
strip();
|
|
||||||
AudioEncoder::operator=( encoder);
|
|
||||||
init( encoder.sink.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the version string of the underlying aacplus library.
|
|
||||||
*
|
|
||||||
* @return the version string of the underlying aacplus library.
|
|
||||||
*/
|
|
||||||
inline const char *
|
|
||||||
getAacPlusVersion( void )
|
|
||||||
{
|
|
||||||
char * id;
|
|
||||||
//char * copyright;
|
|
||||||
|
|
||||||
/* aacplusEncGetVersion(&id, ©right); */
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check wether encoding is in progress.
|
|
||||||
*
|
|
||||||
* @return true if encoding is in progress, false otherwise.
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isRunning ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start encoding. This function returns as soon as possible,
|
|
||||||
* with encoding started in the background.
|
|
||||||
*
|
|
||||||
* @return true if encoding has started, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
start ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
return open();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop encoding. Stops the encoding running in the background.
|
|
||||||
*
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
inline virtual void
|
|
||||||
stop ( void ) throw ( Exception )
|
|
||||||
{
|
|
||||||
return close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open an encoding session.
|
|
||||||
*
|
|
||||||
* @return true if opening was successfull, false otherwise.
|
|
||||||
* @exception Exception
|
|
||||||
*/
|
|
||||||
virtual bool
|
|
||||||
open ( void ) throw ( Exception );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the encoding session is open.
|
|
||||||
*
|
|
||||||
* @return true if the encoding session is open, false otherwise.
|
|
||||||
*/
|
|
||||||
inline virtual bool
|
|
||||||
isOpen ( void ) const throw ()
|
|
||||||
{
|
|
||||||
return aacplusOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 /* AACP_ENCODER_H */
|
|
||||||
|
|
|
@ -1,797 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright: (C) 2000 Julius O. Smith
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
* Julius O. Smith jos@ccrma.stanford.edu
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/* This code was modified by Bruce Forsberg (forsberg@tns.net) to make it
|
|
||||||
into a C++ class
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include "aflibConverter.h"
|
|
||||||
#include "aflibConverterLargeFilter.h"
|
|
||||||
#include "aflibConverterSmallFilter.h"
|
|
||||||
|
|
||||||
#include "aflibDebug.h"
|
|
||||||
|
|
||||||
#if (!defined(TRUE) || !defined(FALSE))
|
|
||||||
# define TRUE 1
|
|
||||||
# define FALSE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The configuration constants below govern
|
|
||||||
* the number of bits in the input sample and filter coefficients, the
|
|
||||||
* number of bits to the right of the binary-point for fixed-point math, etc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Conversion constants */
|
|
||||||
#define Nhc 8
|
|
||||||
#define Na 7
|
|
||||||
#define Np (Nhc+Na)
|
|
||||||
#define Npc (1<<Nhc)
|
|
||||||
#define Amask ((1<<Na)-1)
|
|
||||||
#define Pmask ((1<<Np)-1)
|
|
||||||
#define Nh 16
|
|
||||||
#define Nb 16
|
|
||||||
#define Nhxn 14
|
|
||||||
#define Nhg (Nh-Nhxn)
|
|
||||||
#define NLpScl 13
|
|
||||||
/* Description of constants:
|
|
||||||
*
|
|
||||||
* Npc - is the number of look-up values available for the lowpass filter
|
|
||||||
* between the beginning of its impulse response and the "cutoff time"
|
|
||||||
* of the filter. The cutoff time is defined as the reciprocal of the
|
|
||||||
* lowpass-filter cut off frequence in Hz. For example, if the
|
|
||||||
* lowpass filter were a sinc function, Npc would be the index of the
|
|
||||||
* impulse-response lookup-table corresponding to the first zero-
|
|
||||||
* crossing of the sinc function. (The inverse first zero-crossing
|
|
||||||
* time of a sinc function equals its nominal cutoff frequency in Hz.)
|
|
||||||
* Npc must be a power of 2 due to the details of the current
|
|
||||||
* implementation. The default value of 512 is sufficiently high that
|
|
||||||
* using linear interpolation to fill in between the table entries
|
|
||||||
* gives approximately 16-bit accuracy in filter coefficients.
|
|
||||||
*
|
|
||||||
* Nhc - is log base 2 of Npc.
|
|
||||||
*
|
|
||||||
* Na - is the number of bits devoted to linear interpolation of the
|
|
||||||
* filter coefficients.
|
|
||||||
*
|
|
||||||
* Np - is Na + Nhc, the number of bits to the right of the binary point
|
|
||||||
* in the integer "time" variable. To the left of the point, it indexes
|
|
||||||
* the input array (X), and to the right, it is interpreted as a number
|
|
||||||
* between 0 and 1 sample of the input X. Np must be less than 16 in
|
|
||||||
* this implementation.
|
|
||||||
*
|
|
||||||
* Nh - is the number of bits in the filter coefficients. The sum of Nh and
|
|
||||||
* the number of bits in the input data (typically 16) cannot exceed 32.
|
|
||||||
* Thus Nh should be 16. The largest filter coefficient should nearly
|
|
||||||
* fill 16 bits (32767).
|
|
||||||
*
|
|
||||||
* Nb - is the number of bits in the input data. The sum of Nb and Nh cannot
|
|
||||||
* exceed 32.
|
|
||||||
*
|
|
||||||
* Nhxn - is the number of bits to right shift after multiplying each input
|
|
||||||
* sample times a filter coefficient. It can be as great as Nh and as
|
|
||||||
* small as 0. Nhxn = Nh-2 gives 2 guard bits in the multiply-add
|
|
||||||
* accumulation. If Nhxn=0, the accumulation will soon overflow 32 bits.
|
|
||||||
*
|
|
||||||
* Nhg - is the number of guard bits in mpy-add accumulation (equal to Nh-Nhxn)
|
|
||||||
*
|
|
||||||
* NLpScl - is the number of bits allocated to the unity-gain normalization
|
|
||||||
* factor. The output of the lowpass filter is multiplied by LpScl and
|
|
||||||
* then right-shifted NLpScl bits. To avoid overflow, we must have
|
|
||||||
* Nb+Nhg+NLpScl < 32.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
aflibConverter::aflibConverter(
|
|
||||||
bool high_quality,
|
|
||||||
bool linear_interpolation,
|
|
||||||
bool filter_interpolation)
|
|
||||||
{
|
|
||||||
/* TODO put all these into an enum as it only makes sense to have
|
|
||||||
* one true at a time. - DAS
|
|
||||||
*/
|
|
||||||
interpFilt = filter_interpolation;
|
|
||||||
largeFilter = high_quality;
|
|
||||||
linearInterp = linear_interpolation;
|
|
||||||
|
|
||||||
_II = NULL;
|
|
||||||
_JJ = NULL;
|
|
||||||
_vol = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
aflibConverter::~aflibConverter()
|
|
||||||
{
|
|
||||||
deleteMemory();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
aflibConverter::deleteMemory()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// Delete memory for the input and output arrays
|
|
||||||
if (_II != NULL)
|
|
||||||
{
|
|
||||||
for (i = 0; i < _nChans; i++)
|
|
||||||
{
|
|
||||||
delete [] _II[i];
|
|
||||||
_II[i] = NULL;
|
|
||||||
delete [] _JJ[i];
|
|
||||||
_JJ[i] = NULL;
|
|
||||||
}
|
|
||||||
delete [] _II;
|
|
||||||
_II = NULL;
|
|
||||||
delete [] _JJ;
|
|
||||||
_JJ = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
aflibConverter::initialize(
|
|
||||||
double fac,
|
|
||||||
int channels,
|
|
||||||
double volume)
|
|
||||||
{
|
|
||||||
// This function will allow one to stream data. When a new data stream is to
|
|
||||||
// be input then this function should be called. Even if the factor and number
|
|
||||||
// of channels don't change. Otherwise each new data block sent to resample
|
|
||||||
// will be considered part of the previous data block. This function also allows
|
|
||||||
// one to specified a multiplication factor to adjust the final output. This
|
|
||||||
// applies to the small and large filter.
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// Delete all previous allocated input and output buffer memory
|
|
||||||
deleteMemory();
|
|
||||||
|
|
||||||
_factor = fac;
|
|
||||||
_nChans = channels;
|
|
||||||
_initial = TRUE;
|
|
||||||
_vol = volume;
|
|
||||||
|
|
||||||
// Allocate all new memory
|
|
||||||
_II = new short * [_nChans];
|
|
||||||
_JJ = new short * [_nChans];
|
|
||||||
|
|
||||||
for (i = 0; i < _nChans; i++)
|
|
||||||
{
|
|
||||||
// Add extra to allow of offset of input data (Xoff in main routine)
|
|
||||||
_II[i] = new short[IBUFFSIZE + 256];
|
|
||||||
_JJ[i] = new short[(int)(((double)IBUFFSIZE)*_factor)];
|
|
||||||
memset(_II[i], 0, sizeof(short) * (IBUFFSIZE + 256));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
aflibConverter::resample( /* number of output samples returned */
|
|
||||||
int& inCount, /* number of input samples to convert */
|
|
||||||
int outCount, /* number of output samples to compute */
|
|
||||||
short inArray[], /* input data */
|
|
||||||
short outArray[]) /* output data */
|
|
||||||
{
|
|
||||||
int Ycount;
|
|
||||||
|
|
||||||
|
|
||||||
// Use fast method with no filtering. Poor quality
|
|
||||||
if (linearInterp == TRUE)
|
|
||||||
Ycount = resampleFast(inCount,outCount,inArray,outArray);
|
|
||||||
// Use small filtering. Good qulaity
|
|
||||||
else if (largeFilter == FALSE)
|
|
||||||
Ycount = resampleWithFilter(inCount,outCount,inArray,outArray,
|
|
||||||
SMALL_FILTER_IMP, SMALL_FILTER_IMPD,
|
|
||||||
(unsigned short)(SMALL_FILTER_SCALE * _vol),
|
|
||||||
SMALL_FILTER_NMULT, SMALL_FILTER_NWING);
|
|
||||||
// Use large filtering Great quality
|
|
||||||
else
|
|
||||||
Ycount = resampleWithFilter(inCount,outCount,inArray,outArray,
|
|
||||||
LARGE_FILTER_IMP, LARGE_FILTER_IMPD,
|
|
||||||
(unsigned short)(LARGE_FILTER_SCALE * _vol),
|
|
||||||
LARGE_FILTER_NMULT, LARGE_FILTER_NWING);
|
|
||||||
|
|
||||||
_initial = FALSE;
|
|
||||||
|
|
||||||
return (Ycount);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
aflibConverter::err_ret(char *s)
|
|
||||||
{
|
|
||||||
aflib_debug("resample: %s \n\n",s); /* Display error message */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
aflibConverter::readData(
|
|
||||||
int inCount, /* _total_ number of frames in input file */
|
|
||||||
short inArray[], /* input data */
|
|
||||||
short *outPtr[], /* array receiving chan samps */
|
|
||||||
int dataArraySize, /* size of these arrays */
|
|
||||||
int Xoff, /* read into input array starting at this index */
|
|
||||||
bool init_count)
|
|
||||||
{
|
|
||||||
int i, Nsamps, c;
|
|
||||||
static unsigned int framecount; /* frames previously read */
|
|
||||||
short *ptr;
|
|
||||||
|
|
||||||
if (init_count == TRUE)
|
|
||||||
framecount = 0; /* init this too */
|
|
||||||
|
|
||||||
Nsamps = dataArraySize - Xoff; /* Calculate number of samples to get */
|
|
||||||
|
|
||||||
// Don't overrun input buffers
|
|
||||||
if (Nsamps > (inCount - (int)framecount))
|
|
||||||
{
|
|
||||||
Nsamps = inCount - framecount;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (c = 0; c < _nChans; c++)
|
|
||||||
{
|
|
||||||
ptr = outPtr[c];
|
|
||||||
ptr += Xoff; /* Start at designated sample number */
|
|
||||||
|
|
||||||
for (i = 0; i < Nsamps; i++)
|
|
||||||
*ptr++ = (short) inArray[c * inCount + i + framecount];
|
|
||||||
}
|
|
||||||
|
|
||||||
framecount += Nsamps;
|
|
||||||
|
|
||||||
if ((int)framecount >= inCount) /* return index of last samp */
|
|
||||||
return (((Nsamps - (framecount - inCount)) - 1) + Xoff);
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
aflibConverter::SrcLinear(
|
|
||||||
short X[],
|
|
||||||
short Y[],
|
|
||||||
double factor,
|
|
||||||
unsigned int *Time,
|
|
||||||
unsigned short& Nx,
|
|
||||||
unsigned short Nout)
|
|
||||||
{
|
|
||||||
short iconst;
|
|
||||||
short *Xp, *Ystart;
|
|
||||||
int v,x1,x2;
|
|
||||||
|
|
||||||
double dt; /* Step through input signal */
|
|
||||||
unsigned int dtb; /* Fixed-point version of Dt */
|
|
||||||
// unsigned int endTime; /* When Time reaches EndTime, return to user */
|
|
||||||
unsigned int start_sample, end_sample;
|
|
||||||
|
|
||||||
dt = 1.0/factor; /* Output sampling period */
|
|
||||||
dtb = (unsigned int)(dt*(1<<Np) + 0.5); /* Fixed-point representation */
|
|
||||||
|
|
||||||
start_sample = (*Time)>>Np;
|
|
||||||
Ystart = Y;
|
|
||||||
// endTime = *Time + (1<<Np)*(int)Nx;
|
|
||||||
/*
|
|
||||||
* TODO
|
|
||||||
* DAS: not sure why this was changed from *Time < endTime
|
|
||||||
* update: *Time < endTime causes seg fault. Also adds a clicking sound.
|
|
||||||
*/
|
|
||||||
while (Y - Ystart != Nout)
|
|
||||||
// while (*Time < endTime)
|
|
||||||
{
|
|
||||||
iconst = (*Time) & Pmask;
|
|
||||||
Xp = &X[(*Time)>>Np]; /* Ptr to current input sample */
|
|
||||||
x1 = *Xp++;
|
|
||||||
x2 = *Xp;
|
|
||||||
x1 *= ((1<<Np)-iconst);
|
|
||||||
x2 *= iconst;
|
|
||||||
v = x1 + x2;
|
|
||||||
*Y++ = WordToHword(v,Np); /* Deposit output */
|
|
||||||
*Time += dtb; /* Move to next sample by time increment */
|
|
||||||
}
|
|
||||||
end_sample = (*Time)>>Np;
|
|
||||||
Nx = end_sample - start_sample;
|
|
||||||
return (Y - Ystart); /* Return number of output samples */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
aflibConverter::SrcUp(
|
|
||||||
short X[],
|
|
||||||
short Y[],
|
|
||||||
double factor,
|
|
||||||
unsigned int *Time,
|
|
||||||
unsigned short& Nx,
|
|
||||||
unsigned short Nout,
|
|
||||||
unsigned short Nwing,
|
|
||||||
unsigned short LpScl,
|
|
||||||
short Imp[],
|
|
||||||
short ImpD[],
|
|
||||||
bool Interp)
|
|
||||||
{
|
|
||||||
short *Xp, *Ystart;
|
|
||||||
int v;
|
|
||||||
|
|
||||||
double dt; /* Step through input signal */
|
|
||||||
unsigned int dtb; /* Fixed-point version of Dt */
|
|
||||||
// unsigned int endTime; /* When Time reaches EndTime, return to user */
|
|
||||||
unsigned int start_sample, end_sample;
|
|
||||||
|
|
||||||
dt = 1.0/factor; /* Output sampling period */
|
|
||||||
dtb = (unsigned int)(dt*(1<<Np) + 0.5); /* Fixed-point representation */
|
|
||||||
|
|
||||||
start_sample = (*Time)>>Np;
|
|
||||||
Ystart = Y;
|
|
||||||
// endTime = *Time + (1<<Np)*(int)Nx;
|
|
||||||
/*
|
|
||||||
* TODO
|
|
||||||
* DAS: not sure why this was changed from *Time < endTime
|
|
||||||
* update: *Time < endTime causes seg fault. Also adds a clicking sound.
|
|
||||||
*/
|
|
||||||
while (Y - Ystart != Nout)
|
|
||||||
// while (*Time < endTime)
|
|
||||||
{
|
|
||||||
Xp = &X[*Time>>Np]; /* Ptr to current input sample */
|
|
||||||
/* Perform left-wing inner product */
|
|
||||||
v = FilterUp(Imp, ImpD, Nwing, Interp, Xp, (short)(*Time&Pmask),-1);
|
|
||||||
/* Perform right-wing inner product */
|
|
||||||
v += FilterUp(Imp, ImpD, Nwing, Interp, Xp+1,
|
|
||||||
(short)((((*Time)^Pmask)+1)&Pmask), 1);
|
|
||||||
v >>= Nhg; /* Make guard bits */
|
|
||||||
v *= LpScl; /* Normalize for unity filter gain */
|
|
||||||
*Y++ = WordToHword(v,NLpScl); /* strip guard bits, deposit output */
|
|
||||||
*Time += dtb; /* Move to next sample by time increment */
|
|
||||||
}
|
|
||||||
end_sample = (*Time)>>Np;
|
|
||||||
Nx = end_sample - start_sample;
|
|
||||||
return (Y - Ystart); /* Return the number of output samples */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
aflibConverter::SrcUD(
|
|
||||||
short X[],
|
|
||||||
short Y[],
|
|
||||||
double factor,
|
|
||||||
unsigned int *Time,
|
|
||||||
unsigned short& Nx,
|
|
||||||
unsigned short Nout,
|
|
||||||
unsigned short Nwing,
|
|
||||||
unsigned short LpScl,
|
|
||||||
short Imp[],
|
|
||||||
short ImpD[],
|
|
||||||
bool Interp)
|
|
||||||
{
|
|
||||||
short *Xp, *Ystart;
|
|
||||||
int v;
|
|
||||||
|
|
||||||
double dh; /* Step through filter impulse response */
|
|
||||||
double dt; /* Step through input signal */
|
|
||||||
// unsigned int endTime; /* When Time reaches EndTime, return to user */
|
|
||||||
unsigned int dhb, dtb; /* Fixed-point versions of Dh,Dt */
|
|
||||||
unsigned int start_sample, end_sample;
|
|
||||||
|
|
||||||
dt = 1.0/factor; /* Output sampling period */
|
|
||||||
dtb = (unsigned int)(dt*(1<<Np) + 0.5); /* Fixed-point representation */
|
|
||||||
|
|
||||||
dh = MIN(Npc, factor*Npc); /* Filter sampling period */
|
|
||||||
dhb = (unsigned int)(dh*(1<<Na) + 0.5); /* Fixed-point representation */
|
|
||||||
|
|
||||||
start_sample = (*Time)>>Np;
|
|
||||||
Ystart = Y;
|
|
||||||
// endTime = *Time + (1<<Np)*(int)Nx;
|
|
||||||
/*
|
|
||||||
* TODO
|
|
||||||
* DAS: not sure why this was changed from *Time < endTime
|
|
||||||
* update: *Time < endTime causes seg fault. Also adds a clicking sound.
|
|
||||||
*/
|
|
||||||
while (Y - Ystart != Nout)
|
|
||||||
// while (*Time < endTime)
|
|
||||||
{
|
|
||||||
Xp = &X[*Time>>Np]; /* Ptr to current input sample */
|
|
||||||
v = FilterUD(Imp, ImpD, Nwing, Interp, Xp, (short)(*Time&Pmask),
|
|
||||||
-1, dhb); /* Perform left-wing inner product */
|
|
||||||
v += FilterUD(Imp, ImpD, Nwing, Interp, Xp+1,
|
|
||||||
(short)((((*Time)^Pmask)+1)&Pmask), 1, dhb); /* Perform right-wing inner product */
|
|
||||||
v >>= Nhg; /* Make guard bits */
|
|
||||||
v *= LpScl; /* Normalize for unity filter gain */
|
|
||||||
*Y++ = WordToHword(v,NLpScl); /* strip guard bits, deposit output */
|
|
||||||
*Time += dtb; /* Move to next sample by time increment */
|
|
||||||
}
|
|
||||||
|
|
||||||
end_sample = (*Time)>>Np;
|
|
||||||
Nx = end_sample - start_sample;
|
|
||||||
return (Y - Ystart); /* Return the number of output samples */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
aflibConverter::resampleFast( /* number of output samples returned */
|
|
||||||
int& inCount, /* number of input samples to convert */
|
|
||||||
int outCount, /* number of output samples to compute */
|
|
||||||
short inArray[], /* input data */
|
|
||||||
short outArray[]) /* output data */
|
|
||||||
{
|
|
||||||
unsigned int Time2; /* Current time/pos in input sample */
|
|
||||||
#if 0
|
|
||||||
unsigned short Ncreep;
|
|
||||||
#endif
|
|
||||||
unsigned short Xp, Xoff, Xread;
|
|
||||||
int OBUFFSIZE = (int)(((double)IBUFFSIZE)*_factor);
|
|
||||||
unsigned short Nout = 0, Nx, orig_Nx;
|
|
||||||
unsigned short maxOutput;
|
|
||||||
int total_inCount = 0;
|
|
||||||
int c, i, Ycount, last;
|
|
||||||
bool first_pass = TRUE;
|
|
||||||
|
|
||||||
|
|
||||||
Xoff = 10;
|
|
||||||
|
|
||||||
Nx = IBUFFSIZE - 2*Xoff; /* # of samples to process each iteration */
|
|
||||||
last = 0; /* Have not read last input sample yet */
|
|
||||||
Ycount = 0; /* Current sample and length of output file */
|
|
||||||
|
|
||||||
Xp = Xoff; /* Current "now"-sample pointer for input */
|
|
||||||
Xread = Xoff; /* Position in input array to read into */
|
|
||||||
|
|
||||||
if (_initial == TRUE)
|
|
||||||
_Time = (Xoff<<Np); /* Current-time pointer for converter */
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (!last) /* If haven't read last sample yet */
|
|
||||||
{
|
|
||||||
last = readData(inCount, inArray, _II,
|
|
||||||
IBUFFSIZE, (int)Xread,first_pass);
|
|
||||||
first_pass = FALSE;
|
|
||||||
if (last && (last-Xoff<Nx)) { /* If last sample has been read... */
|
|
||||||
Nx = last-Xoff; /* ...calc last sample affected by filter */
|
|
||||||
if (Nx <= 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((outCount-Ycount) > (OBUFFSIZE - (2*Xoff*_factor)) )
|
|
||||||
maxOutput = OBUFFSIZE - (unsigned short)(2*Xoff*_factor);
|
|
||||||
else
|
|
||||||
maxOutput = outCount-Ycount;
|
|
||||||
|
|
||||||
for (c = 0; c < _nChans; c++)
|
|
||||||
{
|
|
||||||
orig_Nx = Nx;
|
|
||||||
Time2 = _Time;
|
|
||||||
/* Resample stuff in input buffer */
|
|
||||||
Nout=SrcLinear(_II[c],_JJ[c],_factor,&Time2,orig_Nx,maxOutput);
|
|
||||||
}
|
|
||||||
Nx = orig_Nx;
|
|
||||||
_Time = Time2;
|
|
||||||
|
|
||||||
_Time -= (Nx<<Np); /* Move converter Nx samples back in time */
|
|
||||||
Xp += Nx; /* Advance by number of samples processed */
|
|
||||||
#if 0
|
|
||||||
Ncreep = (Time>>Np) - Xoff; /* Calc time accumulation in Time */
|
|
||||||
if (Ncreep) {
|
|
||||||
Time -= (Ncreep<<Np); /* Remove time accumulation */
|
|
||||||
Xp += Ncreep; /* and add it to read pointer */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
for (c = 0; c < _nChans; c++)
|
|
||||||
{
|
|
||||||
for (i=0; i<IBUFFSIZE-Xp+Xoff; i++) { /* Copy part of input signal */
|
|
||||||
_II[c][i] = _II[c][i+Xp-Xoff]; /* that must be re-used */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (last) { /* If near end of sample... */
|
|
||||||
last -= Xp; /* ...keep track were it ends */
|
|
||||||
if (!last) /* Lengthen input by 1 sample if... */
|
|
||||||
last++; /* ...needed to keep flag TRUE */
|
|
||||||
}
|
|
||||||
Xread = IBUFFSIZE - Nx; /* Pos in input buff to read new data into */
|
|
||||||
Xp = Xoff;
|
|
||||||
|
|
||||||
Ycount += Nout;
|
|
||||||
if (Ycount>outCount) {
|
|
||||||
Nout -= (Ycount-outCount);
|
|
||||||
Ycount = outCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Nout > OBUFFSIZE) /* Check to see if output buff overflowed */
|
|
||||||
return err_ret("Output array overflow");
|
|
||||||
|
|
||||||
for (c = 0; c < _nChans; c++)
|
|
||||||
for (i = 0; i < Nout; i++)
|
|
||||||
outArray[c * outCount + i + Ycount - Nout] = _JJ[c][i];
|
|
||||||
|
|
||||||
total_inCount += Nx;
|
|
||||||
|
|
||||||
} while (Ycount < outCount); /* Continue until done */
|
|
||||||
|
|
||||||
inCount = total_inCount;
|
|
||||||
|
|
||||||
return(Ycount); /* Return # of samples in output file */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
aflibConverter::resampleWithFilter( /* number of output samples returned */
|
|
||||||
int& inCount, /* number of input samples to convert */
|
|
||||||
int outCount, /* number of output samples to compute */
|
|
||||||
short inArray[], /* input data */
|
|
||||||
short outArray[], /* output data */
|
|
||||||
short Imp[], short ImpD[],
|
|
||||||
unsigned short LpScl, unsigned short Nmult, unsigned short Nwing)
|
|
||||||
{
|
|
||||||
unsigned int Time2; /* Current time/pos in input sample */
|
|
||||||
#if 0
|
|
||||||
unsigned short Ncreep;
|
|
||||||
#endif
|
|
||||||
unsigned short Xp, Xoff, Xread;
|
|
||||||
int OBUFFSIZE = (int)(((double)IBUFFSIZE)*_factor);
|
|
||||||
unsigned short Nout = 0, Nx, orig_Nx;
|
|
||||||
unsigned short maxOutput;
|
|
||||||
int total_inCount = 0;
|
|
||||||
int c, i, Ycount, last;
|
|
||||||
bool first_pass = TRUE;
|
|
||||||
|
|
||||||
|
|
||||||
/* Account for increased filter gain when using factors less than 1 */
|
|
||||||
if (_factor < 1)
|
|
||||||
LpScl = (unsigned short)(LpScl*_factor + 0.5);
|
|
||||||
|
|
||||||
/* Calc reach of LP filter wing & give some creeping room */
|
|
||||||
Xoff = (unsigned short)(((Nmult+1)/2.0) * MAX(1.0,1.0/_factor) + 10);
|
|
||||||
|
|
||||||
if (IBUFFSIZE < 2*Xoff) /* Check input buffer size */
|
|
||||||
return err_ret("IBUFFSIZE (or factor) is too small");
|
|
||||||
|
|
||||||
Nx = IBUFFSIZE - 2*Xoff; /* # of samples to process each iteration */
|
|
||||||
|
|
||||||
last = 0; /* Have not read last input sample yet */
|
|
||||||
Ycount = 0; /* Current sample and length of output file */
|
|
||||||
Xp = Xoff; /* Current "now"-sample pointer for input */
|
|
||||||
Xread = Xoff; /* Position in input array to read into */
|
|
||||||
|
|
||||||
if (_initial == TRUE)
|
|
||||||
_Time = (Xoff<<Np); /* Current-time pointer for converter */
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (!last) /* If haven't read last sample yet */
|
|
||||||
{
|
|
||||||
last = readData(inCount, inArray, _II,
|
|
||||||
IBUFFSIZE, (int)Xread,first_pass);
|
|
||||||
first_pass = FALSE;
|
|
||||||
if (last && (last-Xoff<Nx)) { /* If last sample has been read... */
|
|
||||||
Nx = last-Xoff; /* ...calc last sample affected by filter */
|
|
||||||
if (Nx <= 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (outCount-Ycount) > (OBUFFSIZE - (2*Xoff*_factor)) )
|
|
||||||
maxOutput = OBUFFSIZE - (unsigned short)(2*Xoff*_factor);
|
|
||||||
else
|
|
||||||
maxOutput = outCount-Ycount;
|
|
||||||
|
|
||||||
for (c = 0; c < _nChans; c++)
|
|
||||||
{
|
|
||||||
orig_Nx = Nx;
|
|
||||||
Time2 = _Time;
|
|
||||||
/* Resample stuff in input buffer */
|
|
||||||
if (_factor >= 1) { /* SrcUp() is faster if we can use it */
|
|
||||||
Nout=SrcUp(_II[c],_JJ[c],_factor,
|
|
||||||
&Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Nout=SrcUD(_II[c],_JJ[c],_factor,
|
|
||||||
&Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_Time = Time2;
|
|
||||||
|
|
||||||
_Time -= (Nx<<Np); /* Move converter Nx samples back in time */
|
|
||||||
Xp += Nx; /* Advance by number of samples processed */
|
|
||||||
#if 0
|
|
||||||
Ncreep = (Time>>Np) - Xoff; /* Calc time accumulation in Time */
|
|
||||||
if (Ncreep) {
|
|
||||||
Time -= (Ncreep<<Np); /* Remove time accumulation */
|
|
||||||
Xp += Ncreep; /* and add it to read pointer */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (last) { /* If near end of sample... */
|
|
||||||
last -= Xp; /* ...keep track were it ends */
|
|
||||||
if (!last) /* Lengthen input by 1 sample if... */
|
|
||||||
last++; /* ...needed to keep flag TRUE */
|
|
||||||
}
|
|
||||||
|
|
||||||
Ycount += Nout;
|
|
||||||
if (Ycount > outCount) {
|
|
||||||
Nout -= (Ycount - outCount);
|
|
||||||
Ycount = outCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Nout > OBUFFSIZE) /* Check to see if output buff overflowed */
|
|
||||||
return err_ret("Output array overflow");
|
|
||||||
|
|
||||||
for (c = 0; c < _nChans; c++)
|
|
||||||
{
|
|
||||||
for (i = 0; i < Nout; i++)
|
|
||||||
{
|
|
||||||
outArray[c * outCount + i + Ycount - Nout] = _JJ[c][i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int act_incount = (int)Nx;
|
|
||||||
|
|
||||||
for (c = 0; c < _nChans; c++)
|
|
||||||
{
|
|
||||||
for (i=0; i<IBUFFSIZE-act_incount+Xoff; i++) { /* Copy part of input signal */
|
|
||||||
_II[c][i] = _II[c][i+act_incount]; /* that must be re-used */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Xread = IBUFFSIZE - Nx; /* Pos in input buff to read new data into */
|
|
||||||
Xp = Xoff;
|
|
||||||
|
|
||||||
total_inCount += Nx;
|
|
||||||
|
|
||||||
} while (Ycount < outCount); /* Continue until done */
|
|
||||||
|
|
||||||
inCount = total_inCount;
|
|
||||||
|
|
||||||
return(Ycount); /* Return # of samples in output file */
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
aflibConverter::FilterUp(
|
|
||||||
short Imp[],
|
|
||||||
short ImpD[],
|
|
||||||
unsigned short Nwing,
|
|
||||||
bool Interp,
|
|
||||||
short *Xp,
|
|
||||||
short Ph,
|
|
||||||
short Inc)
|
|
||||||
{
|
|
||||||
short *Hp, *Hdp = NULL, *End;
|
|
||||||
short a = 0;
|
|
||||||
int v, t;
|
|
||||||
|
|
||||||
v=0;
|
|
||||||
Hp = &Imp[Ph>>Na];
|
|
||||||
End = &Imp[Nwing];
|
|
||||||
|
|
||||||
if (Interp)
|
|
||||||
{
|
|
||||||
Hdp = &ImpD[Ph>>Na];
|
|
||||||
a = Ph & Amask;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Inc == 1) /* If doing right wing... */
|
|
||||||
{ /* ...drop extra coeff, so when Ph is */
|
|
||||||
End--; /* 0.5, we don't do too many mult's */
|
|
||||||
if (Ph == 0) /* If the phase is zero... */
|
|
||||||
{ /* ...then we've already skipped the */
|
|
||||||
Hp += Npc; /* first sample, so we must also */
|
|
||||||
Hdp += Npc; /* skip ahead in Imp[] and ImpD[] */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Interp)
|
|
||||||
{
|
|
||||||
while (Hp < End)
|
|
||||||
{
|
|
||||||
t = *Hp; /* Get filter coeff */
|
|
||||||
t += (((int)*Hdp)*a)>>Na; /* t is now interp'd filter coeff */
|
|
||||||
Hdp += Npc; /* Filter coeff differences step */
|
|
||||||
t *= *Xp; /* Mult coeff by input sample */
|
|
||||||
if (t & (1<<(Nhxn-1))) /* Round, if needed */
|
|
||||||
t += (1<<(Nhxn-1));
|
|
||||||
t >>= Nhxn; /* Leave some guard bits, but come back some */
|
|
||||||
v += t; /* The filter output */
|
|
||||||
Hp += Npc; /* Filter coeff step */
|
|
||||||
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (Hp < End)
|
|
||||||
{
|
|
||||||
t = *Hp; /* Get filter coeff */
|
|
||||||
t *= *Xp; /* Mult coeff by input sample */
|
|
||||||
if (t & (1<<(Nhxn-1))) /* Round, if needed */
|
|
||||||
t += (1<<(Nhxn-1));
|
|
||||||
t >>= Nhxn; /* Leave some guard bits, but come back some */
|
|
||||||
v += t; /* The filter output */
|
|
||||||
Hp += Npc; /* Filter coeff step */
|
|
||||||
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
aflibConverter::FilterUD(
|
|
||||||
short Imp[],
|
|
||||||
short ImpD[],
|
|
||||||
unsigned short Nwing,
|
|
||||||
bool Interp,
|
|
||||||
short *Xp,
|
|
||||||
short Ph,
|
|
||||||
short Inc,
|
|
||||||
unsigned short dhb)
|
|
||||||
{
|
|
||||||
short a;
|
|
||||||
short *Hp, *Hdp, *End;
|
|
||||||
int v, t;
|
|
||||||
unsigned int Ho;
|
|
||||||
|
|
||||||
v=0;
|
|
||||||
Ho = (Ph*(unsigned int)dhb)>>Np;
|
|
||||||
End = &Imp[Nwing];
|
|
||||||
if (Inc == 1) /* If doing right wing... */
|
|
||||||
{ /* ...drop extra coeff, so when Ph is */
|
|
||||||
End--; /* 0.5, we don't do too many mult's */
|
|
||||||
if (Ph == 0) /* If the phase is zero... */
|
|
||||||
Ho += dhb; /* ...then we've already skipped the */
|
|
||||||
} /* first sample, so we must also */
|
|
||||||
/* skip ahead in Imp[] and ImpD[] */
|
|
||||||
|
|
||||||
if (Interp)
|
|
||||||
{
|
|
||||||
while ((Hp = &Imp[Ho>>Na]) < End)
|
|
||||||
{
|
|
||||||
t = *Hp; /* Get IR sample */
|
|
||||||
Hdp = &ImpD[Ho>>Na]; /* get interp (lower Na) bits from diff table*/
|
|
||||||
a = Ho & Amask; /* a is logically between 0 and 1 */
|
|
||||||
t += (((int)*Hdp)*a)>>Na; /* t is now interp'd filter coeff */
|
|
||||||
t *= *Xp; /* Mult coeff by input sample */
|
|
||||||
if (t & 1<<(Nhxn-1)) /* Round, if needed */
|
|
||||||
t += 1<<(Nhxn-1);
|
|
||||||
t >>= Nhxn; /* Leave some guard bits, but come back some */
|
|
||||||
v += t; /* The filter output */
|
|
||||||
Ho += dhb; /* IR step */
|
|
||||||
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while ((Hp = &Imp[Ho>>Na]) < End)
|
|
||||||
{
|
|
||||||
t = *Hp; /* Get IR sample */
|
|
||||||
t *= *Xp; /* Mult coeff by input sample */
|
|
||||||
if (t & 1<<(Nhxn-1)) /* Round, if needed */
|
|
||||||
t += 1<<(Nhxn-1);
|
|
||||||
t >>= Nhxn; /* Leave some guard bits, but come back some */
|
|
||||||
v += t; /* The filter output */
|
|
||||||
Ho += dhb; /* IR step */
|
|
||||||
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(v);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,236 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright: (C) 2000 Julius O. Smith
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
* Julius O. Smith jos@ccrma.stanford.edu
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/* This code was modified by Bruce Forsberg (forsberg@tns.net) to make it
|
|
||||||
into a C++ class
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _AFLIBCONVERTER_H_
|
|
||||||
#define _AFLIBCONVERTER_H_
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MAX
|
|
||||||
#define MAX(x,y) ((x)>(y) ?(x):(y))
|
|
||||||
#endif
|
|
||||||
#ifndef MIN
|
|
||||||
#define MIN(x,y) ((x)<(y) ?(x):(y))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_HWORD (32767)
|
|
||||||
#define MIN_HWORD (-32768)
|
|
||||||
|
|
||||||
#define IBUFFSIZE 4096 /* Input buffer size */
|
|
||||||
|
|
||||||
/*! \class aflibConverter
|
|
||||||
\brief Provides sample rate conversion.
|
|
||||||
|
|
||||||
This class will perform audio resampling. With the constructor you can choose the
|
|
||||||
type of resampling to be done. Simple linear interpolation can be done by setting
|
|
||||||
linear_interpolation to be TRUE in the constructor. The other two flags are
|
|
||||||
ignored if this is set. If linear_interpolation is FALSE then some form of filtering
|
|
||||||
will be done. IF high_quality is FALSE then a small filter will be performed.
|
|
||||||
If high_quality is TRUE then a large filter (higher quality) will be performed. For
|
|
||||||
both the small and large filters another parameter can be specified, filter_interpolation.
|
|
||||||
With filter_interpolation set then the filter coefficients used for both the small and
|
|
||||||
large filtering will be interpolated as well.
|
|
||||||
|
|
||||||
This class was designed to stream audio data. It also expects audio data as 16 bit values.
|
|
||||||
Each time a new stream is started some initialization needs to be done. Thus the function
|
|
||||||
initialize should be called to initialize everything. This initialize function will set
|
|
||||||
the conversion factor as well as a multiplecation factor for volume. The volume only
|
|
||||||
applies to the small and large filter. Since this filter uses a history of the audio data
|
|
||||||
it is possible for it to vary in amplitude. This allows users to scale the data. This
|
|
||||||
class will work on any number of channels. Once everything is specified then resample
|
|
||||||
should be called as many times as is necessary to process all the data. The value
|
|
||||||
inCount will be returned indicating how many inArray samples were actually used to
|
|
||||||
produce the output. This value can be used to indicate where the next block of
|
|
||||||
inArray data should start. The resample function is driven by the outCount value
|
|
||||||
specified. The inArray should contain at least:
|
|
||||||
outCount / factor + extra_samples.
|
|
||||||
extra_samples depends on the type of filtering done. As a rule of thumb 50 should be
|
|
||||||
adequate for any type of filter.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class aflibData;
|
|
||||||
|
|
||||||
class aflibConverter {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Available contructors and destructors
|
|
||||||
aflibConverter (
|
|
||||||
bool high_quality,
|
|
||||||
bool linear_interpolation,
|
|
||||||
bool filter_interpolation);
|
|
||||||
|
|
||||||
~aflibConverter();
|
|
||||||
|
|
||||||
void
|
|
||||||
initialize(
|
|
||||||
double factor, /* factor = Sndout/Sndin */
|
|
||||||
int channels, /* number of sound channels */
|
|
||||||
double volume = 1.0); /* factor to multiply amplitude */
|
|
||||||
|
|
||||||
int
|
|
||||||
resample( /* number of output samples returned */
|
|
||||||
int& inCount, /* number of input samples to convert */
|
|
||||||
int outCount, /* number of output samples to compute */
|
|
||||||
short inArray[], /* input array data (length inCount * nChans) */
|
|
||||||
short outArray[]);/* output array data (length outCount * nChans) */
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
aflibConverter();
|
|
||||||
|
|
||||||
aflibConverter(const aflibConverter& op);
|
|
||||||
|
|
||||||
const aflibConverter&
|
|
||||||
operator=(const aflibConverter& op);
|
|
||||||
|
|
||||||
int
|
|
||||||
err_ret(char *s);
|
|
||||||
|
|
||||||
void
|
|
||||||
deleteMemory();
|
|
||||||
|
|
||||||
int
|
|
||||||
readData(
|
|
||||||
int inCount, /* _total_ number of frames in input file */
|
|
||||||
short inArray[], /* input data */
|
|
||||||
short *outPtr[], /* array receiving chan samps */
|
|
||||||
int dataArraySize, /* size of these arrays */
|
|
||||||
int Xoff, /* read into input array starting at this index */
|
|
||||||
bool init_count);
|
|
||||||
|
|
||||||
|
|
||||||
inline short
|
|
||||||
WordToHword(int v, int scl)
|
|
||||||
{
|
|
||||||
short out;
|
|
||||||
int llsb = (1<<(scl-1));
|
|
||||||
v += llsb; /* round */
|
|
||||||
v >>= scl;
|
|
||||||
if (v>MAX_HWORD) {
|
|
||||||
v = MAX_HWORD;
|
|
||||||
} else if (v < MIN_HWORD) {
|
|
||||||
v = MIN_HWORD;
|
|
||||||
}
|
|
||||||
out = (short) v;
|
|
||||||
return out;
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
|
||||||
SrcLinear(
|
|
||||||
short X[],
|
|
||||||
short Y[],
|
|
||||||
double factor,
|
|
||||||
unsigned int *Time,
|
|
||||||
unsigned short& Nx,
|
|
||||||
unsigned short Nout);
|
|
||||||
|
|
||||||
int
|
|
||||||
SrcUp(
|
|
||||||
short X[],
|
|
||||||
short Y[],
|
|
||||||
double factor,
|
|
||||||
unsigned int *Time,
|
|
||||||
unsigned short& Nx,
|
|
||||||
unsigned short Nout,
|
|
||||||
unsigned short Nwing,
|
|
||||||
unsigned short LpScl,
|
|
||||||
short Imp[],
|
|
||||||
short ImpD[],
|
|
||||||
bool Interp);
|
|
||||||
|
|
||||||
int
|
|
||||||
SrcUD(
|
|
||||||
short X[],
|
|
||||||
short Y[],
|
|
||||||
double factor,
|
|
||||||
unsigned int *Time,
|
|
||||||
unsigned short& Nx,
|
|
||||||
unsigned short Nout,
|
|
||||||
unsigned short Nwing,
|
|
||||||
unsigned short LpScl,
|
|
||||||
short Imp[],
|
|
||||||
short ImpD[],
|
|
||||||
bool Interp);
|
|
||||||
|
|
||||||
int
|
|
||||||
FilterUp(
|
|
||||||
short Imp[],
|
|
||||||
short ImpD[],
|
|
||||||
unsigned short Nwing,
|
|
||||||
bool Interp,
|
|
||||||
short *Xp,
|
|
||||||
short Ph,
|
|
||||||
short Inc);
|
|
||||||
|
|
||||||
int
|
|
||||||
FilterUD(
|
|
||||||
short Imp[],
|
|
||||||
short ImpD[],
|
|
||||||
unsigned short Nwing,
|
|
||||||
bool Interp,
|
|
||||||
short *Xp,
|
|
||||||
short Ph,
|
|
||||||
short Inc,
|
|
||||||
unsigned short dhb);
|
|
||||||
|
|
||||||
int
|
|
||||||
resampleFast( /* number of output samples returned */
|
|
||||||
int& inCount, /* number of input samples to convert */
|
|
||||||
int outCount, /* number of output samples to compute */
|
|
||||||
short inArray[], /* input array data (length inCount * nChans) */
|
|
||||||
short outArray[]);/* output array data (length outCount * nChans) */
|
|
||||||
|
|
||||||
int
|
|
||||||
resampleWithFilter( /* number of output samples returned */
|
|
||||||
int& inCount, /* number of input samples to convert */
|
|
||||||
int outCount, /* number of output samples to compute */
|
|
||||||
short inArray[], /* input array data (length inCount * nChans) */
|
|
||||||
short outArray[], /* output array data (length outCount * nChans) */
|
|
||||||
short Imp[], short ImpD[],
|
|
||||||
unsigned short LpScl, unsigned short Nmult, unsigned short Nwing);
|
|
||||||
|
|
||||||
|
|
||||||
static short SMALL_FILTER_IMP[];
|
|
||||||
static short LARGE_FILTER_IMP[];
|
|
||||||
|
|
||||||
bool interpFilt;
|
|
||||||
bool largeFilter;
|
|
||||||
bool linearInterp;
|
|
||||||
short ** _II;
|
|
||||||
short ** _JJ;
|
|
||||||
unsigned int _Time;
|
|
||||||
double _factor;
|
|
||||||
int _nChans;
|
|
||||||
bool _initial;
|
|
||||||
double _vol;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,228 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
Copyright (C) 2000 Stefan Westerfeld
|
|
||||||
stefan@space.twc.de
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public License
|
|
||||||
along with this library; see the file COPYING.LIB. If not, write to
|
|
||||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
||||||
Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "aflibDebug.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
static int aflib_debug_level = ::aflibDebug::lInfo;
|
|
||||||
static bool aflib_debug_abort = false;
|
|
||||||
static const char *aflib_debug_prefix = "";
|
|
||||||
static char *messageAppName = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
static char* status_strs[] =
|
|
||||||
{
|
|
||||||
"Success",
|
|
||||||
"Error Open",
|
|
||||||
"Unsupported",
|
|
||||||
"AFLIB_ERROR_INITIALIZATION_FAILURE",
|
|
||||||
"AFLIB_NOT_FOUND",
|
|
||||||
"AFLIB_END_OF_FILE",
|
|
||||||
"AFLIB_NO_DATA",
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static char* data_size_strs[] =
|
|
||||||
{
|
|
||||||
"UNDEFINED",
|
|
||||||
"8 bit signed",
|
|
||||||
"8 bit unsigned",
|
|
||||||
"16 bit signed",
|
|
||||||
"16 bit unsigned",
|
|
||||||
"32 bit signed",
|
|
||||||
"32 bit unsigned",
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
static char* data_endian_strs[] =
|
|
||||||
{
|
|
||||||
"UNDEFINED",
|
|
||||||
"ENDIAN_LITTLE",
|
|
||||||
"ENDIAN_BIG",
|
|
||||||
0
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Call the graphical application to display a message, if
|
|
||||||
* defined. Otherwise, send to standard error. Debug messages are
|
|
||||||
* always sent to standard error because they tend to be very verbose.
|
|
||||||
* Note that the external application is run in the background to
|
|
||||||
* avoid blocking the sound server.
|
|
||||||
*/
|
|
||||||
void output_message(::aflibDebug::Level level, const char *msg) {
|
|
||||||
char buff[1024];
|
|
||||||
|
|
||||||
/* default to text output if no message app is defined or if it is a debug message. */
|
|
||||||
if (messageAppName == 0 || !strcmp(messageAppName, "") || (level == ::aflibDebug::lDebug))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s\n", msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (level) {
|
|
||||||
case ::aflibDebug::lFatal:
|
|
||||||
sprintf(buff, "%s -e \"aflib fatal error:\n\n%s\" &", messageAppName, msg);
|
|
||||||
break;
|
|
||||||
case ::aflibDebug::lWarning:
|
|
||||||
sprintf(buff, "%s -w \"aflib warning message:\n\n%s\" &", messageAppName, msg);
|
|
||||||
break;
|
|
||||||
case ::aflibDebug::lInfo:
|
|
||||||
sprintf(buff, "%s -i \"aflib informational message:\n\n%s\" &", messageAppName, msg);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break; // avoid compile warning
|
|
||||||
}
|
|
||||||
system(buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Display a message using output_message. If the message is the same
|
|
||||||
* as the previous one, just increment a count but don't display
|
|
||||||
* it. This prevents flooding the user with duplicate warnings. If the
|
|
||||||
* message is not the same as the previous one, then we report the
|
|
||||||
* previously repeated message (if any) and reset the last message and
|
|
||||||
* count.
|
|
||||||
*/
|
|
||||||
void display_message(::aflibDebug::Level level, const char *msg) {
|
|
||||||
static char lastMsg[1024];
|
|
||||||
static ::aflibDebug::Level lastLevel;
|
|
||||||
static int msgCount = 0;
|
|
||||||
|
|
||||||
if (!strncmp(msg, lastMsg, 1024))
|
|
||||||
{
|
|
||||||
msgCount++;
|
|
||||||
} else {
|
|
||||||
if (msgCount > 0)
|
|
||||||
{
|
|
||||||
char buff[1024];
|
|
||||||
sprintf(buff, "%s\n(The previous message was repeated %d times.)", lastMsg, msgCount);
|
|
||||||
output_message(lastLevel, buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(lastMsg, msg, 1024);
|
|
||||||
lastLevel = level;
|
|
||||||
msgCount = 0;
|
|
||||||
output_message(level, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static class DebugInitFromEnv {
|
|
||||||
|
|
||||||
public:
|
|
||||||
DebugInitFromEnv() {
|
|
||||||
const char *env = getenv("AFLIB_DEBUG");
|
|
||||||
if(env)
|
|
||||||
{
|
|
||||||
if(strcmp(env,"debug") == 0)
|
|
||||||
aflib_debug_level = ::aflibDebug::lDebug;
|
|
||||||
else if(strcmp(env,"info") == 0)
|
|
||||||
aflib_debug_level = ::aflibDebug::lInfo;
|
|
||||||
else if(strcmp(env,"warning") == 0)
|
|
||||||
aflib_debug_level = ::aflibDebug::lWarning;
|
|
||||||
else if(strcmp(env,"quiet") == 0)
|
|
||||||
aflib_debug_level = ::aflibDebug::lFatal;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr,
|
|
||||||
"AFLIB_DEBUG must be one of debug,info,warning,quiet\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
env = getenv("AFLIB_DEBUG_ABORT");
|
|
||||||
if(env)
|
|
||||||
aflib_debug_abort = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debugInitFromEnv;
|
|
||||||
|
|
||||||
|
|
||||||
void aflibDebug::init(const char *prefix, Level level)
|
|
||||||
{
|
|
||||||
aflib_debug_level = level;
|
|
||||||
aflib_debug_prefix = prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
void aflibDebug::fatal(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
char buff[1024];
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vsprintf(buff, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
display_message(::aflibDebug::lFatal, buff);
|
|
||||||
|
|
||||||
if(aflib_debug_abort) abort();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void aflibDebug::warning(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
if(lWarning >= aflib_debug_level)
|
|
||||||
{
|
|
||||||
char buff[1024];
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vsprintf(buff, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
display_message(::aflibDebug::lWarning, buff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void aflibDebug::info(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
if(lInfo >= aflib_debug_level)
|
|
||||||
{
|
|
||||||
char buff[1024];
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vsprintf(buff, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
display_message(::aflibDebug::lInfo, buff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void aflibDebug::debug(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
if(lDebug >= aflib_debug_level)
|
|
||||||
{
|
|
||||||
char buff[1024];
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vsprintf(buff, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
display_message(::aflibDebug::lDebug, buff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void aflibDebug::messageApp(const char *appName)
|
|
||||||
{
|
|
||||||
messageAppName = (char*) realloc(messageAppName, strlen(appName)+1);
|
|
||||||
strcpy(messageAppName, appName);
|
|
||||||
}
|
|
|
@ -1,118 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
Copyright (C) 2000 Stefan Westerfeld
|
|
||||||
stefan@space.twc.de
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public License
|
|
||||||
along with this library; see the file COPYING.LIB. If not, write to
|
|
||||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
||||||
Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
|
|
||||||
Some inspiration taken from glib.
|
|
||||||
Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
|
||||||
Modified by the GLib Team and others 1997-1999.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _AFLIBDEBUG_H_
|
|
||||||
#define _AFLIBDEBUG_H_
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BC - Status (2000-09-30): Debug.
|
|
||||||
*
|
|
||||||
* Collection class, no instance, no members. Thus binary compatible (will
|
|
||||||
* be kept).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define aflib_fatal ::aflibDebug::fatal
|
|
||||||
#define aflib_warning ::aflibDebug::warning
|
|
||||||
#define aflib_info ::aflibDebug::info
|
|
||||||
#define aflib_debug ::aflibDebug::debug
|
|
||||||
|
|
||||||
/* source compatibility with older sources */
|
|
||||||
#define aflibdebug ::aflibDebug::debug
|
|
||||||
#define setaflibdebug(x) aflib_warning("setaflibdebug is obsolete")
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
|
|
||||||
#define aflib_return_if_fail(expr) \
|
|
||||||
if (!(expr)) \
|
|
||||||
{ \
|
|
||||||
aflib_warning ("file %s: line %d (%s): assertion failed: (%s)", \
|
|
||||||
__FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \
|
|
||||||
return; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define aflib_return_val_if_fail(expr,val) \
|
|
||||||
if (!(expr)) \
|
|
||||||
{ \
|
|
||||||
aflib_warning ("file %s: line %d (%s): assertion failed: (%s)", \
|
|
||||||
__FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \
|
|
||||||
return (val); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define aflib_assert(expr) \
|
|
||||||
if (!(expr)) \
|
|
||||||
aflib_fatal ("file %s: line %d (%s): assertion failed: (%s)", \
|
|
||||||
__FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define aflib_return_if_fail(expr) \
|
|
||||||
if (!(expr)) \
|
|
||||||
{ \
|
|
||||||
aflib_warning ("file %s: line %d: assertion failed: (%s)", \
|
|
||||||
__FILE__, __LINE__, #expr); \
|
|
||||||
return; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define aflib_return_val_if_fail(expr,val) \
|
|
||||||
if (!(expr)) \
|
|
||||||
{ \
|
|
||||||
aflib_warning ("file %s: line %d: assertion failed: (%s)", \
|
|
||||||
__FILE__, __LINE__, #expr); \
|
|
||||||
return (val); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define aflib_assert(expr) \
|
|
||||||
if (!(expr)) \
|
|
||||||
aflib_fatal ("file %s: line %d: assertion failed: (%s)", \
|
|
||||||
__FILE__, __LINE__, #expr); \
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class aflibDebug {
|
|
||||||
public:
|
|
||||||
enum Level { lFatal = 3, lWarning = 2, lInfo = 1, lDebug = 0 };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes at which is the minimum level to react to. If you
|
|
||||||
* call this, call this before creating the Arts::Dispatcher object.
|
|
||||||
*/
|
|
||||||
static void init(const char *prefix, Level level);
|
|
||||||
|
|
||||||
static void fatal(const char *fmt,...); // print on stderr & abort
|
|
||||||
static void warning(const char *fmt,...); // print on stderr
|
|
||||||
static void info(const char *fmt,...); // print on stdout
|
|
||||||
static void debug(const char *fmt,...); // print on stdout
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method sets the name of an external application to
|
|
||||||
* display messages graphically.
|
|
||||||
*/
|
|
||||||
static void messageApp(const char *appName);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,193 +0,0 @@
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved.
|
|
||||||
|
|
||||||
Tyrell DarkIce
|
|
||||||
|
|
||||||
File : main.cpp
|
|
||||||
Version : $Revision$
|
|
||||||
Author : $Author$
|
|
||||||
Location : $HeadURL$
|
|
||||||
|
|
||||||
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 <stdlib.h>
|
|
||||||
#else
|
|
||||||
#error needs stdlib.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SIGNAL_H
|
|
||||||
#include <signal.h>
|
|
||||||
#else
|
|
||||||
#error needs signal.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include "Ref.h"
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "DarkIce.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* =================================================== local data structures */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* The DarkIce object we're running
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static Ref<DarkIce> darkice;
|
|
||||||
|
|
||||||
|
|
||||||
/* ================================================ local constants & macros */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* File identity
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char fileid[] = "$Id$";
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Default config file name
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static const char *DEFAULT_CONFIG_FILE = "/etc/darkice.cfg";
|
|
||||||
|
|
||||||
|
|
||||||
/* =============================================== local function prototypes */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Show program usage
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static void
|
|
||||||
showUsage ( std::ostream & os );
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Handler for the SIGUSR1 signal
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static void
|
|
||||||
sigusr1Handler(int value);
|
|
||||||
|
|
||||||
|
|
||||||
/* ============================================================= module code */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Program entry point
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
int
|
|
||||||
main (
|
|
||||||
int argc,
|
|
||||||
char * argv[] )
|
|
||||||
{
|
|
||||||
int res = -1;
|
|
||||||
|
|
||||||
std::cout << "DarkIce " << VERSION
|
|
||||||
<< " live audio streamer, http://darkice.tyrell.hu/"
|
|
||||||
<< std::endl
|
|
||||||
<< "Copyright (c) 2000-2007, Tyrell Hungary, http://tyrell.hu/"
|
|
||||||
<< std::endl << std::endl;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const char * configFileName = DEFAULT_CONFIG_FILE;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "Using config file: " << configFileName << std::endl;
|
|
||||||
|
|
||||||
std::ifstream configFile( configFileName);
|
|
||||||
Reporter::setReportVerbosity( verbosity );
|
|
||||||
Reporter::setReportOutputStream( std::cout );
|
|
||||||
Config config( configFile);
|
|
||||||
|
|
||||||
darkice = new DarkIce( config);
|
|
||||||
|
|
||||||
signal(SIGUSR1, sigusr1Handler);
|
|
||||||
|
|
||||||
res = darkice->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
|
|
||||||
<< " if not specified, /etc/darkice.cfg is used"
|
|
||||||
<< std::endl
|
|
||||||
<< " -v n verbosity level (0 = silent, 10 = loud)"
|
|
||||||
<< std::endl
|
|
||||||
<< " -h print this message and exit"
|
|
||||||
<< std::endl
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
|
||||||
* Handle the SIGUSR1 signal here
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
static void
|
|
||||||
sigusr1Handler(int value)
|
|
||||||
{
|
|
||||||
darkice->cut();
|
|
||||||
}
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue