~ft/faad2

c7dc7254c1ecfeb2227275f56bddac4f4e822760 — menno 19 years ago
no message
162 files changed, 55610 insertions(+), 0 deletions(-)

A AUTHORS
A COPYING
A ChangeLog
A NEWS
A README
A TODO
A common/faad/aacinfo.c
A common/faad/aacinfo.dsp
A common/faad/aacinfo.dsw
A common/faad/aacinfo.h
A common/faad/filestream.c
A common/faad/filestream.h
A common/faad/getopt.c
A common/faad/getopt.h
A common/faad/id3v2tag.c
A common/faad/id3v2tag.h
A common/libsndfile/AUTHORS
A common/libsndfile/COPYING
A common/libsndfile/ChangeLog
A common/libsndfile/INSTALL
A common/libsndfile/MacOS/MacOS-readme.txt
A common/libsndfile/MacOS/Makefile.am
A common/libsndfile/MacOS/Makefile.in
A common/libsndfile/MacOS/config.h
A common/libsndfile/Makefile.am
A common/libsndfile/Makefile.in
A common/libsndfile/NEWS
A common/libsndfile/README
A common/libsndfile/TODO
A common/libsndfile/Win32/Makefile.am
A common/libsndfile/Win32/Makefile.in
A common/libsndfile/Win32/README-Win32.txt
A common/libsndfile/Win32/README-Win32.txt.old
A common/libsndfile/Win32/config.h
A common/libsndfile/Win32/libsndfile.dsp
A common/libsndfile/Win32/libsndfile.dsw
A common/libsndfile/Win32/unistd.h
A common/libsndfile/acconfig.h
A common/libsndfile/aclocal.m4
A common/libsndfile/check_libsndfile.py
A common/libsndfile/config.guess
A common/libsndfile/config.sub
A common/libsndfile/configure
A common/libsndfile/configure.in
A common/libsndfile/install-sh
A common/libsndfile/libsndfile.spec
A common/libsndfile/libsndfile.spec.in
A common/libsndfile/ltconfig
A common/libsndfile/ltmain.sh
A common/libsndfile/missing
A common/libsndfile/mkinstalldirs
A common/libsndfile/reconf
A common/libsndfile/src/G72x/ChangeLog
A common/libsndfile/src/G72x/Makefile.am
A common/libsndfile/src/G72x/Makefile.in
A common/libsndfile/src/G72x/README
A common/libsndfile/src/G72x/README.original
A common/libsndfile/src/G72x/g721.c
A common/libsndfile/src/G72x/g723_16.c
A common/libsndfile/src/G72x/g723_24.c
A common/libsndfile/src/G72x/g723_40.c
A common/libsndfile/src/G72x/g72x.c
A common/libsndfile/src/G72x/g72x.h
A common/libsndfile/src/G72x/private.h
A common/libsndfile/src/GSM610/COPYRIGHT
A common/libsndfile/src/GSM610/ChangeLog
A common/libsndfile/src/GSM610/Makefile.am
A common/libsndfile/src/GSM610/Makefile.in
A common/libsndfile/src/GSM610/README
A common/libsndfile/src/GSM610/add.c
A common/libsndfile/src/GSM610/code.c
A common/libsndfile/src/GSM610/config.h
A common/libsndfile/src/GSM610/decode.c
A common/libsndfile/src/GSM610/gsm.h
A common/libsndfile/src/GSM610/gsm_create.c
A common/libsndfile/src/GSM610/gsm_decode.c
A common/libsndfile/src/GSM610/gsm_destroy.c
A common/libsndfile/src/GSM610/gsm_encode.c
A common/libsndfile/src/GSM610/gsm_option.c
A common/libsndfile/src/GSM610/long_term.c
A common/libsndfile/src/GSM610/lpc.c
A common/libsndfile/src/GSM610/preprocess.c
A common/libsndfile/src/GSM610/private.h
A common/libsndfile/src/GSM610/proto.h
A common/libsndfile/src/GSM610/rpe.c
A common/libsndfile/src/GSM610/short_term.c
A common/libsndfile/src/GSM610/table.c
A common/libsndfile/src/GSM610/unproto.h
A common/libsndfile/src/Makefile.am
A common/libsndfile/src/Makefile.in
A common/libsndfile/src/aiff.c
A common/libsndfile/src/alaw.c
A common/libsndfile/src/au.c
A common/libsndfile/src/au.h
A common/libsndfile/src/au_g72x.c
A common/libsndfile/src/common.c
A common/libsndfile/src/common.h
A common/libsndfile/src/config.h.in
A common/libsndfile/src/float32.c
A common/libsndfile/src/floatcast.h
A common/libsndfile/src/ircam.c
A common/libsndfile/src/nist.c
A common/libsndfile/src/paf.c
A common/libsndfile/src/pcm.c
A common/libsndfile/src/raw.c
A common/libsndfile/src/samplitude.c
A common/libsndfile/src/sfendian.h
A common/libsndfile/src/sndfile.c
A common/libsndfile/src/sndfile.h
A common/libsndfile/src/stamp-h.in
A common/libsndfile/src/svx.c
A common/libsndfile/src/ulaw.c
A common/libsndfile/src/voc.c
A common/libsndfile/src/wav.c
A common/libsndfile/src/wav.h
A common/libsndfile/src/wav_gsm610.c
A common/libsndfile/src/wav_ima_adpcm.c
A common/libsndfile/src/wav_ms_adpcm.c
A frontend/faad.dsp
A frontend/faad.dsw
A frontend/main.c
A include/faad.h
A libfaad/bits.c
A libfaad/bits.h
A libfaad/data.c
A libfaad/data.h
A libfaad/decoder.c
A libfaad/decoder.h
A libfaad/drc.c
A libfaad/drc.h
A libfaad/error.c
A libfaad/error.h
A libfaad/filtbank.c
A libfaad/filtbank.h
A libfaad/huffman.c
A libfaad/huffman.h
A libfaad/ic_predict.c
A libfaad/ic_predict.h
A libfaad/is.c
A libfaad/is.h
A libfaad/kbd_win.h
A libfaad/libfaad.dsp
A libfaad/libfaad.dsw
A libfaad/lt_predict.c
A libfaad/lt_predict.h
A libfaad/mdct.c
A libfaad/mdct.h
A libfaad/ms.c
A libfaad/ms.h
A libfaad/output.c
A libfaad/output.h
A libfaad/pns.c
A libfaad/pns.h
A libfaad/predict.c
A libfaad/pulse.c
A libfaad/pulse.h
A libfaad/specrec.c
A libfaad/specrec.h
A libfaad/syntax.c
A libfaad/syntax.h
A libfaad/tns.c
A libfaad/tns.h
A  => AUTHORS +4 -0
@@ 1,4 @@

menno (menno@audiocoding.com)
 - complete library


A  => COPYING +340 -0
@@ 1,340 @@
		    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) 19yy  <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) 19yy 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.

A  => ChangeLog +2 -0
@@ 1,2 @@

Initial revision
\ No newline at end of file

A  => NEWS +3 -0
@@ 1,3 @@

14 Januari 2002
 - Initial revision of completely rewritten FAAD 2 library
\ No newline at end of file

A  => README +44 -0
@@ 1,44 @@
Freeware Advanced Audio Decoder version 2
http://www.audiocoding.com/

FAAD 2 is a LC, MAIN and LTP profile, MPEG2 and MPEG-4 AAC decoder, completely
written from scratch. FAAD 2 is licensed under the GPL.


__________
COPYRIGHTS

For FAAD the following license applies:

******************************************************************************
FAAD - Freeware Advanced Audio Decoder
Copyright (C) 2002 M. Bakker
 
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.
******************************************************************************


Please note that the use of this software may require the payment of
patent royalties. You need to consider this issue before you start
building derivative works. We are not warranting or indemnifying you in
any way for patent royalities! YOU ARE SOLELY RESPONSIBLE FOR YOUR OWN
ACTIONS!


______
PEOPLE

FAAD2 is completely written by:
 - menno (menno@audiocoding.com).

A  => TODO +15 -0
@@ 1,15 @@

- Small fixes to PNS (see pns.c)
- Channel coupling
- Better buffering in frontend (more intelligently handle nr. of channels)
- Lot's of testing
- SSR (???)
- CELP decoder -> AAC scalable profile

- Reintroduce:
 - Winamp plugin
 - Winamp3 plugin
 - Sonique plugin
 - XMMS plugin
 - CoolEdit lugin


A  => common/faad/aacinfo.c +367 -0
@@ 1,367 @@
/*
** FAAD - Freeware Advanced Audio Decoder
** Copyright (C) 2002 M. Bakker
**  
** 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.
**
** $Id: aacinfo.c,v 1.1 2002/01/14 19:15:49 menno Exp $
**/

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include <malloc.h>
#include "filestream.h"
#include "aacinfo.h"

#define ADIF_MAX_SIZE 30 /* Should be enough */
#define ADTS_MAX_SIZE 10 /* Should be enough */

static int sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000};

static int read_ADIF_header(FILE_STREAM *file, faadAACInfo *info)
{
    int bitstream;
    unsigned char buffer[ADIF_MAX_SIZE];
    int skip_size = 0;
    int sf_idx;

    /* Get ADIF header data */
    info->headertype = 1;

    if(read_buffer_filestream(file, buffer, ADIF_MAX_SIZE) < 0)
		return -1;

    /* copyright string */
    if(buffer[0] & 0x80)
        skip_size += 9; /* skip 9 bytes */

    bitstream = buffer[0 + skip_size] & 0x10;
    info->bitrate = ((unsigned int)(buffer[0 + skip_size] & 0x0F)<<19)|
        ((unsigned int)buffer[1 + skip_size]<<11)|
        ((unsigned int)buffer[2 + skip_size]<<3)|
        ((unsigned int)buffer[3 + skip_size] & 0xE0);

    if (bitstream == 0)
    {
        info->object_type =  ((buffer[6 + skip_size]&0x01)<<1)|((buffer[7 + skip_size]&0x80)>>7);
        sf_idx = (buffer[7 + skip_size]&0x78)>>3;
    } else {
        info->object_type = (buffer[4 + skip_size] & 0x18)>>3;
        sf_idx = ((buffer[4 + skip_size] & 0x07)<<1)|((buffer[5 + skip_size] & 0x80)>>7);
    }
    info->sampling_rate = sample_rates[sf_idx];

    return 0;
}

static int read_ADTS_header(FILE_STREAM *file, faadAACInfo *info,
                            unsigned long **seek_table, int *seek_table_len,
                            int tagsize, int no_seek_table)
{
    /* Get ADTS header data */
    unsigned char buffer[ADTS_MAX_SIZE];
    int frames, framesinsec=0, t_framelength = 0, frame_length, sr_idx, ID;
    int second = 0, pos;
	int i;
    float frames_per_sec = 0;
    unsigned long bytes;
	unsigned long *tmp_seek_table = NULL;

    info->headertype = 2;

    /* Read all frames to ensure correct time and bitrate */
    for(frames=0; /* */; frames++, framesinsec++)
    {
		/* If streaming, only go until we hit 5 seconds worth */
		 if(file->http || no_seek_table)
		 {
			 if(frames >= 43 * 5)
			 {
				break;
			 }
		 }

        pos = tell_filestream(file);

        /* 12 bit SYNCWORD */
        bytes = read_buffer_filestream(file, buffer, ADTS_MAX_SIZE);

        if(bytes != ADTS_MAX_SIZE)
        {
            /* Bail out if no syncword found */
            break;
        }

		/* check syncword */
        if (!((buffer[0] == 0xFF)&&((buffer[1] & 0xF6) == 0xF0)))
            break;

        if(!frames)
        {
            /* fixed ADTS header is the same for every frame, so we read it only once */
            /* Syncword found, proceed to read in the fixed ADTS header */
            ID = buffer[1] & 0x08;
            info->object_type = (buffer[2]&0xC0)>>6;
            sr_idx = (buffer[2]&0x3C)>>2;
            info->channels = ((buffer[2]&0x01)<<2)|((buffer[3]&0xC0)>>6);

            frames_per_sec = sample_rates[sr_idx] / 1024.f;
        }

        /* ...and the variable ADTS header */
        if (ID == 0) {
            info->version = 4;
            frame_length = (((unsigned int)buffer[4]) << 5) |
                ((unsigned int)buffer[5] >> 3);
        } else { /* MPEG-2 */
            info->version = 2;
            frame_length = ((((unsigned int)buffer[3] & 0x3)) << 11)
            | (((unsigned int)buffer[4]) << 3) | (buffer[5] >> 5);
        }

        t_framelength += frame_length;

		if(!file->http)
		{
			if(framesinsec == 43)
				framesinsec = 0;

			if(framesinsec == 0 && seek_table_len)
			{
				tmp_seek_table = (unsigned long *) realloc(tmp_seek_table, (second + 1) * sizeof(unsigned long));
				tmp_seek_table[second] = pos;
				second++;
			}
		}

		/* NOTE: While simply skipping ahead by reading may seem to be more work than seeking,
			it is actually much faster, and keeps compatibility with streaming */
		for(i=0; i < frame_length - ADTS_MAX_SIZE; i++)
        {
			if(read_byte_filestream(file) < 0)
				break;
        }
    }

	if(seek_table_len)
	{
		*seek_table_len = second;
		*seek_table = tmp_seek_table;
	}

    info->sampling_rate = sample_rates[sr_idx];
    info->bitrate = (int)(((t_framelength / frames) * (info->sampling_rate/1024.0)) +0.5)*8;

	if(file->http)
	{
		/* Since we only use 5 seconds of aac data to get a rough bitrate, we must use a different
		   method of calculating the overall length */
		if(filelength_filestream(file))
		{
			info->length = (int)((filelength_filestream(file)/(((info->bitrate*8)/1024)*16))*1000);
		}
		else
		{
			/* Since the server didnt tell us how long the file is, 
			   we have no way of determining length */
			info->length = 0;
		}
	}
	else
	{
		info->length = (int)((float)(frames/frames_per_sec))*1000;
	}

    return 0;
}

int get_AAC_format(char *filename, faadAACInfo *info,
                   unsigned long **seek_table, int *seek_table_len,
                   int no_seek_table)
{
    unsigned long tagsize;
    FILE_STREAM *file;
	char buffer[10];
    unsigned long file_len;
    unsigned char adxx_id[5];
    unsigned long tmp;

    memset(info, 0, sizeof(faadAACInfo));

    file = open_filestream(filename);

    if(file == NULL)
        return -1;

    file_len = filelength_filestream(file);

    /* Skip the tag, if it's there */
    tmp = read_buffer_filestream(file, buffer, 10);

    if (StringComp(buffer, "ID3", 3) == 0)
	{
		unsigned int i;

        /* high bit is not used */
        tagsize = (buffer[6] << 21) | (buffer[7] << 14) |
            (buffer[8] <<  7) | (buffer[9] <<  0);

        for(i=0; i < tagsize; i++)
			if(read_byte_filestream(file) < 0)
				return -1;

        tagsize += 10;
    }
	else
	{
        tagsize = 0;

		/* Simple hack to reset to the beginning */
		file->buffer_offset = 0;
		file->file_offset = 0;
    }

	if(file_len)
	    file_len -= tagsize;

    tmp = read_buffer_filestream(file, adxx_id, 2);
    //seek_filestream(file, tagsize, FILE_BEGIN);

    adxx_id[5-1] = 0;
    info->length = 0;

	/* Determine the header type of the file, check the first two bytes */
    if(StringComp(adxx_id, "AD", 2) == 0)
    {
		/* We think its an ADIF header, but check the rest just to make sure */
		tmp = read_buffer_filestream(file, adxx_id + 2, 2);
		
		if(StringComp(adxx_id, "ADIF", 4) == 0)
		{
			read_ADIF_header(file, info);
		}
    }
    else
    {
		/* No ADIF, check for ADTS header */
        if ((adxx_id[0] == 0xFF)&&((adxx_id[1] & 0xF6) == 0xF0))
        {
			/* ADTS  header located */
			/* Since this routine must work for streams, we can't use the seek function to go backwards, thus 
			   we have to use a quick hack as seen below to go back where we need to. */
			
			if(file->buffer_offset >= 2)
			{
				// simple seeking hack, though not really safe, the probability of it causing a problem is low.
				file->buffer_offset -= 2;
				file->file_offset -= 2;
			}

            read_ADTS_header(file, info, seek_table, seek_table_len, tagsize,
                no_seek_table);
        }
        else
        {
            /* Unknown/headerless AAC file, assume format: */
            info->version = 2;
            info->bitrate = 128000;
            info->sampling_rate = 44100;
            info->channels = 2;
            info->headertype = 0;
            info->object_type = 1;
        }
    }

    close_filestream(file);

    return 0;
}

int StringComp(char const *str1, char const *str2, unsigned long len)
{
    signed int c1 = 0, c2 = 0;

    while (len--) {
        c1 = *str1++;
        c2 = *str2++;

        if (c1 == 0 || c1 != c2)
            break;
    }

    return c1 - c2;
}

#ifdef TEST
/* Program to test aacinfo functionality */

#include <stdio.h>

void main(int argc, char *argv[])
{
    faadAACInfo info;
    unsigned long *seek_table = NULL;
    int seek_table_len = 0;
    char *header, *object;

    if (argc < 2)
    {
        fprintf(stderr, "USAGE: aacinfo aacfile.aac\n");
        return;
    }

    get_AAC_format(argv[1], &info, &seek_table, &seek_table_len, 0);

    fprintf(stdout, "MPEG version: %d\n", info.version);
    fprintf(stdout, "channels: %d\n", info.channels);
    fprintf(stdout, "sampling_rate: %d\n", info.sampling_rate);
    fprintf(stdout, "bitrate: %d\n", info.bitrate);
    fprintf(stdout, "length: %.3f\n", (float)info.length/1000.0);

    switch (info.object_type)
    {
    case 0:
        object = "MAIN";
        break;
    case 1:
        object = "LC";
        break;
    case 2:
        object = "SSR";
        break;
    case 3:
        object = "LTP";
        break;
    }
    fprintf(stdout, "object_type: %s\n", object);

    switch (info.headertype)
    {
    case 0:
        header = "RAW";
        break;
    case 1:
        header = "ADIF";
        break;
    case 2:
        header = "ADTS";
        break;
    }
    fprintf(stdout, "headertype: %s\n", header);
}

#endif
\ No newline at end of file

A  => common/faad/aacinfo.dsp +110 -0
@@ 1,110 @@
# Microsoft Developer Studio Project File - Name="aacinfo" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **

# TARGTYPE "Win32 (x86) Console Application" 0x0103

CFG=aacinfo - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE 
!MESSAGE NMAKE /f "aacinfo.mak".
!MESSAGE 
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE 
!MESSAGE NMAKE /f "aacinfo.mak" CFG="aacinfo - Win32 Debug"
!MESSAGE 
!MESSAGE Possible choices for configuration are:
!MESSAGE 
!MESSAGE "aacinfo - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "aacinfo - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE 

# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=xicl6.exe
RSC=rc.exe

!IF  "$(CFG)" == "aacinfo - Win32 Release"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "TEST" /YX /FD /c
# ADD BASE RSC /l 0x413 /d "NDEBUG"
# ADD RSC /l 0x413 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386

!ELSEIF  "$(CFG)" == "aacinfo - Win32 Debug"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "TEST" /YX /FD /GZ /c
# ADD BASE RSC /l 0x413 /d "_DEBUG"
# ADD RSC /l 0x413 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept

!ENDIF 

# Begin Target

# Name "aacinfo - Win32 Release"
# Name "aacinfo - Win32 Debug"
# Begin Group "Source Files"

# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File

SOURCE=.\aacinfo.c
# End Source File
# Begin Source File

SOURCE=.\filestream.c
# End Source File
# End Group
# Begin Group "Header Files"

# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File

SOURCE=.\aacinfo.h
# End Source File
# Begin Source File

SOURCE=.\filestream.h
# End Source File
# End Group
# End Target
# End Project

A  => common/faad/aacinfo.dsw +29 -0
@@ 1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!

###############################################################################

Project: "aacinfo"=.\aacinfo.dsp - Package Owner=<4>

Package=<5>
{{{
}}}

Package=<4>
{{{
}}}

###############################################################################

Global:

Package=<5>
{{{
}}}

Package=<3>
{{{
}}}

###############################################################################


A  => common/faad/aacinfo.h +42 -0
@@ 1,42 @@
/*
** FAAD - Freeware Advanced Audio Decoder
** Copyright (C) 2002 M. Bakker
**  
** 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.
**
** $Id: aacinfo.h,v 1.1 2002/01/14 19:15:49 menno Exp $
**/

#include "filestream.h"

typedef struct {
    int version;
    int channels;
    int sampling_rate;
    int bitrate;
    int length;
    int object_type;
    int headertype;
} faadAACInfo;

int get_AAC_format(char *filename, faadAACInfo *info,
                   unsigned long **seek_table, int *seek_table_len,
                   int no_seek_table);

static int read_ADIF_header(FILE_STREAM *file, faadAACInfo *info);
static int read_ADTS_header(FILE_STREAM *file, faadAACInfo *info,
                            unsigned long **seek_table, int *seek_table_len,
                            int tagsize, int no_seek_table);
int StringComp(char const *str1, char const *str2, unsigned long len);
\ No newline at end of file

A  => common/faad/filestream.c +464 -0
@@ 1,464 @@
/*
** FAAD - Freeware Advanced Audio Decoder
** Copyright (C) 2002 M. Bakker
**  
** 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.
**
** $Id: filestream.c,v 1.1 2002/01/14 19:15:49 menno Exp $
**/

/* Not very portable yet */

#include <winsock2.h> // Note: Must be *before* windows.h
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include "filestream.h"
#include "aacinfo.h"

/* TEMPROARY HACK */
#define CommonExit(A) MessageBox(NULL, A, "FAAD Plugin", MB_OK)

int winsock_init=0; // 0=winsock not initialized, 1=success
long local_buffer_size = 64;
long stream_buffer_size = 128;

FILE_STREAM *open_filestream(char *filename)
{
    FILE_STREAM *fs;

    if(StringComp(filename,"http://", 7) == 0)
    {
        fs = (FILE_STREAM *)LocalAlloc(LPTR, sizeof(FILE_STREAM) + stream_buffer_size * 1024);

        if(fs == NULL)
            return NULL;

        fs->data = (unsigned char *)&fs[1];

        if(http_file_open(filename, fs) < 0)
        {
            LocalFree(fs);
            return NULL;
        }

        fs->http = 1;
    }
    else
    {
        fs = (FILE_STREAM*)LocalAlloc(LPTR, sizeof(FILE_STREAM) + local_buffer_size * 1024);

        if(fs == NULL)
            return NULL;

        fs->data = (unsigned char *)&fs[1];

        fs->stream = CreateFile(filename, GENERIC_READ,
            FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
            OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
        if (fs->stream == INVALID_HANDLE_VALUE)
        {
            LocalFree(fs);
            return NULL;
        }

        fs->http = 0;
    }

    fs->buffer_length = 0;
    fs->buffer_offset = 0;
    fs->file_offset = 0;

    return fs;
}

int read_byte_filestream(FILE_STREAM *fs)
{
    if(fs->buffer_offset == fs->buffer_length)
    {
        fs->buffer_offset = 0;

        if(fs->http)
            fs->buffer_length = recv(fs->inetStream, fs->data, stream_buffer_size * 1024, 0);
        else
            ReadFile(fs->stream, fs->data, local_buffer_size * 1024, &fs->buffer_length, 0);

        if(fs->buffer_length <= 0)
        {
            if(fs->http)
            {
                int x;
                x = WSAGetLastError();

                if(x == 0)
                {
                    /* Equivalent of a successful EOF for HTTP */
                }
            }

            fs->buffer_length = 0;
            return -1;
        }
    }

    fs->file_offset++;

    return fs->data[fs->buffer_offset++];
}

int read_buffer_filestream(FILE_STREAM *fs, void *data, int length)
{
    int i, tmp;
    unsigned char *data2 = (unsigned char *)data;

    for(i=0; i < length; i++)
    {
        if((tmp = read_byte_filestream(fs)) < 0)
        {
            if(i)
			{
                break;
            }
			else
			{
                return -1;
            }
        }
        data2[i] = tmp;
    }

    return i;
}

unsigned long filelength_filestream(FILE_STREAM *fs)
{
    unsigned long fsize;

    if (fs->http)
    {
        fsize = fs->http_file_length;
    }
	else
	{
        fsize = GetFileSize(fs->stream, NULL);
    }

    return fsize;
}

void seek_filestream(FILE_STREAM *fs, unsigned long offset, int mode)
{
    if(fs->http)
    {
        return;
    }

	SetFilePointer(fs->stream, offset, NULL, mode);

	if(mode == FILE_CURRENT)
		fs->file_offset += offset;
	else if(mode == FILE_END)
		fs->file_offset = filelength_filestream(fs) + offset;
	else
		fs->file_offset = offset;

    fs->buffer_length = 0;
    fs->buffer_offset = 0;
}

unsigned long tell_filestream(FILE_STREAM *fs)
{
    return fs->file_offset;
}

void close_filestream(FILE_STREAM *fs)
{
    if(fs)
    {
        if (fs->http)
        {
            if (fs->inetStream)
            {
                /* The 'proper' way to close a TCP connection */
                if(fs->inetStream)
                {
                    CloseTCP(fs->inetStream);
                }
            }
        }
        else
        {
            if(fs->stream)
                CloseHandle(fs->stream);
        }

        LocalFree(fs);
        fs = NULL;
    }
}

int WinsockInit()
{
    /* Before using winsock, you must load the DLL... */
    WSADATA wsaData;

    /* Load version 2.0 */
    if (WSAStartup( MAKEWORD( 2, 0 ), &wsaData ))
    {
        /* Disable streaming */
        return -1;
    }

    winsock_init = 1;

    return 0;
}

void WinsockDeInit()
{
    /* Unload the DLL */

    if(winsock_init)
        WSACleanup();
}

int FindCRLF(char *str)
{
    int i;

    for(i=0; i != lstrlen(str) && str[i] != '\r'; i++);

    return i;
}

void CloseTCP(int s)
{
    char tempbuf[1024];

    /* Set the socket to ignore any new incoming data */
    shutdown(s, 1);

    /* Get any old remaining data */
    while(recv(s, tempbuf, 1024, 0) > 0);

    /* Deallocate the socket */
    closesocket(s);
}

int resolve_host(char *host, SOCKADDR_IN *sck_addr, unsigned short remote_port)
{
    HOSTENT *hp;

    if (isalpha(host[0]))
    {
        /* server address is a name */
        hp = gethostbyname(host);
    }
    else
    {
        unsigned long addr;
        /* Convert nnn.nnn address to a usable one */
        addr = inet_addr(host);
        hp = gethostbyaddr((char *)&addr, 4, AF_INET);
    }

    if (hp == NULL)
    {
        char tmp[128];
        wsprintf(tmp, "Error resolving host address [%s]!\n", host);
        CommonExit(tmp);
        return -1;
    }

    ZeroMemory(sck_addr, sizeof(SOCKADDR_IN));
    sck_addr->sin_family = AF_INET;
    sck_addr->sin_port = htons(remote_port);
    CopyMemory(&sck_addr->sin_addr, hp->h_addr, hp->h_length);

    return 0;
}

int http_file_open(char *url, FILE_STREAM *fs)
{
    SOCKET sck;
    SOCKADDR_IN host;
    char server[1024], file[1024], request[1024], *temp = NULL, *tmpfile = NULL;
    int i, j, port = 80, bytes_recv, http_code;

    /* No winsock, no streaming */
    if(!winsock_init)
    {
        return -1;
    }

    url += 7; // Skip over http://

    /* Extract data from the URL */
    for(i=0; url[i] != '/' && url[i] != ':' && url[i] != 0; i++);

    ZeroMemory(server, 1024);
    CopyMemory(server, url, i);

    if(url[i] == ':')
    {
        /* A certain port was specified */
        port = atol(url + (i + 1));
    }

    for(; url[i] != '/' && url[i] != 0; i++);

    ZeroMemory(file, 1024);

    CopyMemory(file, url + i, lstrlen(url));

    /* END OF URL PARSING */

    /* Create a TCP/IP socket */
    sck = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if(sck == INVALID_SOCKET)
    {
        CommonExit("Error creating TCP/IP new socket");
        return -1;
    }

    /* Resolve the host address (turn www.blah.com into an IP) */
    if(resolve_host(server, &host, (unsigned short)port))
    {
        CommonExit("Error resolving host address");
        CloseTCP(sck);
        return -1;
    }

    /* Connect to the server */
    if(connect(sck, (SOCKADDR *)&host, sizeof(SOCKADDR)) == SOCKET_ERROR)
    {
        CommonExit("Error connecting to remote server");
        CloseTCP(sck);
        return -1;
    }

	tmpfile = calloc(1, (strlen(file) * 3) + 1);

	/* Encode URL */
	for(i=0, j=0; i < (int)strlen(file); i++)
	{
		if((unsigned char)file[i] <= 31 || (unsigned char)file[i] >= 127)
		{
			/* encode ASCII-control characters */
			wsprintf(tmpfile + j, "%%%X", (unsigned char)file[i]);
			j += 3;
			continue;
		}
		else
		{
			switch(file[i])
			{
				/* encode characters that could confuse some servers */
				case ' ':
				case '"':
				case '>':
				case '<':
				case '#':
				case '%':
				case '{':
				case '}':
				case '|':
				case '\\':
				case '^':
				case '~':
				case '[':
				case ']':
				case '`':

				wsprintf(tmpfile + j, "%%%X", (unsigned char)file[i]);
				j += 3;
				continue;
			}
		}
		
		tmpfile[j] = file[i];
		j++;
	}

    wsprintf(request, "GET %s\r\n\r\n", tmpfile);

	free(tmpfile);

    /* Send the request */
    if(send(sck, request, lstrlen(request), 0) <= 0)
    {
        /* Error sending data */
        CloseTCP(sck);
        return -1;
    }

    ZeroMemory(request, 1024);

    /* Send the request */
    if((bytes_recv = recv(sck, request, 1024, 0)) <= 0)
    {
        /* Error sending data */
        CloseTCP(sck);
        return -1;
    }

    if(StringComp(request,"HTTP/1.", 7) != 0)
    {
        /* Invalid header */
        CloseTCP(sck);
        return -1;
    }

    http_code = atol(request + 9);

    if(http_code < 200 || http_code > 299)
    {
        /* HTTP error */
        CloseTCP(sck);
        return -1;
    }

	// Search for a length field
	fs->http_file_length = 0;

    /* Limit search to only 20 loops */
    if((temp = strstr(request, "Content-Length: ")) != NULL)
    {
		/* Has a content-length field, copy into structure */
		fs->http_file_length = atol(temp + 16);
	}

    /* Copy the handle data into the structure */
    fs->inetStream = sck;

    /* Copy any excess data beyond the header into the filestream buffers */
	temp = strstr(request, "\r\n\r\n");

	if(temp)
	{
		temp += 4;
	}

    if(temp - request < bytes_recv)
    {
        memcpy(fs->data, temp, (temp - request) - bytes_recv);
        fs->buffer_length = (temp - request) - bytes_recv;
        fs->buffer_offset = 0;
    }

    return 0;
}

A  => common/faad/filestream.h +51 -0
@@ 1,51 @@
/*
** FAAD - Freeware Advanced Audio Decoder
** Copyright (C) 2002 M. Bakker
**  
** 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.
**
** $Id: filestream.h,v 1.1 2002/01/14 19:15:49 menno Exp $
**/

#ifndef FILESTREAM_H
#define FILESTREAM_H

typedef struct {
    HANDLE stream;
    unsigned short inetStream;
    unsigned char *data;
    int http;
    int buffer_offset;
    int buffer_length;
    int file_offset;
    int http_file_length;
} FILE_STREAM;

extern long local_buffer_size;
extern long stream_buffer_size;

FILE_STREAM *open_filestream(char *filename);
int read_byte_filestream(FILE_STREAM *fs);
int read_buffer_filestream(FILE_STREAM *fs, void *data, int length);
unsigned long filelength_filestream(FILE_STREAM *fs);
void close_filestream(FILE_STREAM *fs);
void seek_filestream(FILE_STREAM *fs, unsigned long offset, int mode);
unsigned long tell_filestream(FILE_STREAM *fs);
int http_file_open(char *url, FILE_STREAM *fs);

int WinsockInit();
void WinsockDeInit();
void CloseTCP(int s);
#endif
\ No newline at end of file

A  => common/faad/getopt.c +755 -0
@@ 1,755 @@
/* Getopt for GNU.
   NOTE: getopt is now part of the C library, so if you don't know what
   "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
   before changing it!

   Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
    Free Software Foundation, Inc.

   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, 675 Mass Ave, Cambridge, MA 02139, USA.  */


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifndef __STDC__
#  ifndef const
#    define const
#  endif
#endif

/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.  */
#ifndef _NO_PROTO
#define _NO_PROTO
#endif

#include <stdio.h>

/* Comment out all this code if we are using the GNU C Library, and are not
   actually compiling the library itself.  This code is part of the GNU C
   Library, but also included in many other GNU distributions.  Compiling
   and linking in this code is a waste when using the GNU C library
   (especially if it is a shared library).  Rather than having every GNU
   program understand `configure --with-gnu-libc' and omit the object files,
   it is simpler to just do this in the source for each such file.  */

#if defined (_LIBC) || !defined (__GNU_LIBRARY__) || !__MacOSX__


/* This needs to come after some library #include
   to get __GNU_LIBRARY__ defined.  */
#ifdef  __GNU_LIBRARY__
/* Don't include stdlib.h for non-GNU C libraries because some of them
   contain conflicting prototypes for getopt.  */
#include <stdlib.h>
#endif  /* GNU C library.  */

/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
   long-named option.  Because this is not POSIX.2 compliant, it is
   being phased out.  */
/* #define GETOPT_COMPAT */

/* This version of `getopt' appears to the caller like standard Unix `getopt'
   but it behaves differently for the user, since it allows the user
   to intersperse the options with the other arguments.

   As `getopt' works, it permutes the elements of ARGV so that,
   when it is done, all the options precede everything else.  Thus
   all application programs are extended to handle flexible argument order.

   Setting the environment variable POSIXLY_CORRECT disables permutation.
   Then the behavior is completely standard.

   GNU application programs can use a third alternative mode in which
   they can distinguish the relative order of options and other arguments.  */

#include "getopt.h"

/* For communication from `getopt' to the caller.
   When `getopt' finds an option that takes an argument,
   the argument value is returned here.
   Also, when `ordering' is RETURN_IN_ORDER,
   each non-option ARGV-element is returned here.  */

char *optarg = 0;

/* Index in ARGV of the next element to be scanned.
   This is used for communication to and from the caller
   and for communication between successive calls to `getopt'.

   On entry to `getopt', zero means this is the first call; initialize.

   When `getopt' returns EOF, this is the index of the first of the
   non-option elements that the caller should itself scan.

   Otherwise, `optind' communicates from one call to the next
   how much of ARGV has been scanned so far.  */

/* XXX 1003.2 says this must be 1 before any call.  */
int optind = 0;

/* The next char to be scanned in the option-element
   in which the last option character we returned was found.
   This allows us to pick up the scan where we left off.

   If this is zero, or a null string, it means resume the scan
   by advancing to the next ARGV-element.  */

static char *nextchar;

/* Callers store zero here to inhibit the error message
   for unrecognized options.  */

int opterr = 1;

/* Set to an option character which was unrecognized.
   This must be initialized on some systems to avoid linking in the
   system's own getopt implementation.  */

#define BAD_OPTION '\0'
int optopt = BAD_OPTION;

/* Describe how to deal with options that follow non-option ARGV-elements.

   If the caller did not specify anything,
   the default is REQUIRE_ORDER if the environment variable
   POSIXLY_CORRECT is defined, PERMUTE otherwise.

   REQUIRE_ORDER means don't recognize them as options;
   stop option processing when the first non-option is seen.
   This is what Unix does.
   This mode of operation is selected by either setting the environment
   variable POSIXLY_CORRECT, or using `+' as the first character
   of the list of option characters.

   PERMUTE is the default.  We permute the contents of ARGV as we scan,
   so that eventually all the non-options are at the end.  This allows options
   to be given in any order, even with programs that were not written to
   expect this.

   RETURN_IN_ORDER is an option available to programs that were written
   to expect options and other ARGV-elements in any order and that care about
   the ordering of the two.  We describe each non-option ARGV-element
   as if it were the argument of an option with character code 1.
   Using `-' as the first character of the list of option characters
   selects this mode of operation.

   The special argument `--' forces an end of option-scanning regardless
   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
   `--' can cause `getopt' to return EOF with `optind' != ARGC.  */

static enum
{
  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} ordering;

#ifdef  __GNU_LIBRARY__
/* We want to avoid inclusion of string.h with non-GNU libraries
   because there are many ways it can cause trouble.
   On some systems, it contains special magic macros that don't work
   in GCC.  */
#include <string.h>
#define my_index    strchr
#define my_strlen   strlen
#else

/* Avoid depending on library functions or files
   whose names are inconsistent.  */

#if __STDC__ || defined(PROTO)
extern char *getenv(const char *name);
extern int  strcmp (const char *s1, const char *s2);
extern int  strncmp(const char *s1, const char *s2, unsigned int n);

static int my_strlen(const char *s);
static char *my_index (const char *str, int chr);
#else
extern char *getenv ();
#endif

static int
my_strlen (str)
     const char *str;
{
  int n = 0;
  while (*str++)
    n++;
  return n;
}

static char *
my_index (str, chr)
     const char *str;
     int chr;
{
  while (*str)
    {
      if (*str == chr)
    return (char *) str;
      str++;
    }
  return 0;
}

#endif              /* GNU C library.  */

/* Handle permutation of arguments.  */

/* Describe the part of ARGV that contains non-options that have
   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
   `last_nonopt' is the index after the last of them.  */

static int first_nonopt;
static int last_nonopt;

/* Exchange two adjacent subsequences of ARGV.
   One subsequence is elements [first_nonopt,last_nonopt)
   which contains all the non-options that have been skipped so far.
   The other is elements [last_nonopt,optind), which contains all
   the options processed since those non-options were skipped.

   `first_nonopt' and `last_nonopt' are relocated so that they describe
   the new indices of the non-options in ARGV after they are moved.

   To perform the swap, we first reverse the order of all elements. So
   all options now come before all non options, but they are in the
   wrong order. So we put back the options and non options in original
   order by reversing them again. For example:
       original input:      a b c -x -y
       reverse all:         -y -x c b a
       reverse options:     -x -y c b a
       reverse non options: -x -y a b c
*/

#if __STDC__ || defined(PROTO)
static void exchange (char **argv);
#endif

static void
exchange (argv)
     char **argv;
{
  char *temp, **first, **last;

  /* Reverse all the elements [first_nonopt, optind) */
  first = &argv[first_nonopt];
  last  = &argv[optind-1];
  while (first < last) {
    temp = *first; *first = *last; *last = temp; first++; last--;
  }
  /* Put back the options in order */
  first = &argv[first_nonopt];
  first_nonopt += (optind - last_nonopt);
  last  = &argv[first_nonopt - 1];
  while (first < last) {
    temp = *first; *first = *last; *last = temp; first++; last--;
  }

  /* Put back the non options in order */
  first = &argv[first_nonopt];
  last_nonopt = optind;
  last  = &argv[last_nonopt-1];
  while (first < last) {
    temp = *first; *first = *last; *last = temp; first++; last--;
  }
}

/* Scan elements of ARGV (whose length is ARGC) for option characters
   given in OPTSTRING.

   If an element of ARGV starts with '-', and is not exactly "-" or "--",
   then it is an option element.  The characters of this element
   (aside from the initial '-') are option characters.  If `getopt'
   is called repeatedly, it returns successively each of the option characters
   from each of the option elements.

   If `getopt' finds another option character, it returns that character,
   updating `optind' and `nextchar' so that the next call to `getopt' can
   resume the scan with the following option character or ARGV-element.

   If there are no more option characters, `getopt' returns `EOF'.
   Then `optind' is the index in ARGV of the first ARGV-element
   that is not an option.  (The ARGV-elements have been permuted
   so that those that are not options now come last.)

   OPTSTRING is a string containing the legitimate option characters.
   If an option character is seen that is not listed in OPTSTRING,
   return BAD_OPTION after printing an error message.  If you set `opterr' to
   zero, the error message is suppressed but we still return BAD_OPTION.

   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
   so the following text in the same ARGV-element, or the text of the following
   ARGV-element, is returned in `optarg'.  Two colons mean an option that
   wants an optional arg; if there is text in the current ARGV-element,
   it is returned in `optarg', otherwise `optarg' is set to zero.

   If OPTSTRING starts with `-' or `+', it requests different methods of
   handling the non-option ARGV-elements.
   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.

   Long-named options begin with `--' instead of `-'.
   Their names may be abbreviated as long as the abbreviation is unique
   or is an exact match for some defined option.  If they have an
   argument, it follows the option name in the same ARGV-element, separated
   from the option name by a `=', or else the in next ARGV-element.
   When `getopt' finds a long-named option, it returns 0 if that option's
   `flag' field is nonzero, the value of the option's `val' field
   if the `flag' field is zero.

   The elements of ARGV aren't really const, because we permute them.
   But we pretend they're const in the prototype to be compatible
   with other systems.

   LONGOPTS is a vector of `struct option' terminated by an
   element containing a name which is zero.

   LONGIND returns the index in LONGOPT of the long-named option found.
   It is only valid when a long-named option has been found by the most
   recent call.

   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
   long-named options.  */

int
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
     int argc;
     char *const *argv;
     const char *optstring;
     const struct option *longopts;
     int *longind;
     int long_only;
{
  int option_index;

  optarg = 0;

  /* Initialize the internal data when the first call is made.
     Start processing options with ARGV-element 1 (since ARGV-element 0
     is the program name); the sequence of previously skipped
     non-option ARGV-elements is empty.  */

  if (optind == 0)
    {
      first_nonopt = last_nonopt = optind = 1;

      nextchar = NULL;

      /* Determine how to handle the ordering of options and nonoptions.  */

      if (optstring[0] == '-')
    {
      ordering = RETURN_IN_ORDER;
      ++optstring;
    }
      else if (optstring[0] == '+')
    {
      ordering = REQUIRE_ORDER;
      ++optstring;
    }
      else if (getenv ("POSIXLY_CORRECT") != NULL)
    ordering = REQUIRE_ORDER;
      else
    ordering = PERMUTE;
    }

  if (nextchar == NULL || *nextchar == '\0')
    {
      if (ordering == PERMUTE)
    {
      /* If we have just processed some options following some non-options,
         exchange them so that the options come first.  */

      if (first_nonopt != last_nonopt && last_nonopt != optind)
        exchange ((char **) argv);
      else if (last_nonopt != optind)
        first_nonopt = optind;

      /* Now skip any additional non-options
         and extend the range of non-options previously skipped.  */

      while (optind < argc
         && (argv[optind][0] != '-' || argv[optind][1] == '\0')
#ifdef GETOPT_COMPAT
         && (longopts == NULL
             || argv[optind][0] != '+' || argv[optind][1] == '\0')
#endif              /* GETOPT_COMPAT */
         )
        optind++;
      last_nonopt = optind;
    }

      /* Special ARGV-element `--' means premature end of options.
     Skip it like a null option,
     then exchange with previous non-options as if it were an option,
     then skip everything else like a non-option.  */

      if (optind != argc && !strcmp (argv[optind], "--"))
    {
      optind++;

      if (first_nonopt != last_nonopt && last_nonopt != optind)
        exchange ((char **) argv);
      else if (first_nonopt == last_nonopt)
        first_nonopt = optind;
      last_nonopt = argc;

      optind = argc;
    }

      /* If we have done all the ARGV-elements, stop the scan
     and back over any non-options that we skipped and permuted.  */

      if (optind == argc)
    {
      /* Set the next-arg-index to point at the non-options
         that we previously skipped, so the caller will digest them.  */
      if (first_nonopt != last_nonopt)
        optind = first_nonopt;
      return EOF;
    }

      /* If we have come to a non-option and did not permute it,
     either stop the scan or describe it to the caller and pass it by.  */

      if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
#ifdef GETOPT_COMPAT
      && (longopts == NULL
          || argv[optind][0] != '+' || argv[optind][1] == '\0')
#endif              /* GETOPT_COMPAT */
      )
    {
      if (ordering == REQUIRE_ORDER)
        return EOF;
      optarg = argv[optind++];
      return 1;
    }

      /* We have found another option-ARGV-element.
     Start decoding its characters.  */

      nextchar = (argv[optind] + 1
          + (longopts != NULL && argv[optind][1] == '-'));
    }

  if (longopts != NULL
      && ((argv[optind][0] == '-'
       && (argv[optind][1] == '-' || long_only))
#ifdef GETOPT_COMPAT
      || argv[optind][0] == '+'
#endif              /* GETOPT_COMPAT */
      ))
    {
      const struct option *p;
      char *s = nextchar;
      int exact = 0;
      int ambig = 0;
      const struct option *pfound = NULL;
      int indfound = 0;

      while (*s && *s != '=')
    s++;

      /* Test all options for either exact match or abbreviated matches.  */
      for (p = longopts, option_index = 0; p->name;
       p++, option_index++)
    if (!strncmp (p->name, nextchar, s - nextchar))
      {
        if (s - nextchar == my_strlen (p->name))
          {
        /* Exact match found.  */
        pfound = p;
        indfound = option_index;
        exact = 1;
        break;
          }
        else if (pfound == NULL)
          {
        /* First nonexact match found.  */
        pfound = p;
        indfound = option_index;
          }
        else
          /* Second nonexact match found.  */
          ambig = 1;
      }

      if (ambig && !exact)
    {
      if (opterr)
        fprintf (stderr, "%s: option `%s' is ambiguous\n",
             argv[0], argv[optind]);
      nextchar += my_strlen (nextchar);
      optind++;
      return BAD_OPTION;
    }

      if (pfound != NULL)
    {
      option_index = indfound;
      optind++;
      if (*s)
        {
          /* Don't test has_arg with >, because some C compilers don't
         allow it to be used on enums.  */
          if (pfound->has_arg)
        optarg = s + 1;
          else
        {
          if (opterr)
            {
              if (argv[optind - 1][1] == '-')
            /* --option */
            fprintf (stderr,
                 "%s: option `--%s' doesn't allow an argument\n",
                 argv[0], pfound->name);
              else
            /* +option or -option */
            fprintf (stderr,
                 "%s: option `%c%s' doesn't allow an argument\n",
                 argv[0], argv[optind - 1][0], pfound->name);
            }
          nextchar += my_strlen (nextchar);
          return BAD_OPTION;
        }
        }
      else if (pfound->has_arg == 1)
        {
          if (optind < argc)
        optarg = argv[optind++];
          else
        {
          if (opterr)
            fprintf (stderr, "%s: option `%s' requires an argument\n",
                 argv[0], argv[optind - 1]);
          nextchar += my_strlen (nextchar);
          return optstring[0] == ':' ? ':' : BAD_OPTION;
        }
        }
      nextchar += my_strlen (nextchar);
      if (longind != NULL)
        *longind = option_index;
      if (pfound->flag)
        {
          *(pfound->flag) = pfound->val;
          return 0;
        }
      return pfound->val;
    }
      /* Can't find it as a long option.  If this is not getopt_long_only,
     or the option starts with '--' or is not a valid short
     option, then it's an error.
     Otherwise interpret it as a short option.  */
      if (!long_only || argv[optind][1] == '-'
#ifdef GETOPT_COMPAT
      || argv[optind][0] == '+'
#endif              /* GETOPT_COMPAT */
      || my_index (optstring, *nextchar) == NULL)
    {
      if (opterr)
        {
          if (argv[optind][1] == '-')
        /* --option */
        fprintf (stderr, "%s: unrecognized option `--%s'\n",
             argv[0], nextchar);
          else
        /* +option or -option */
        fprintf (stderr, "%s: unrecognized option `%c%s'\n",
             argv[0], argv[optind][0], nextchar);
        }
      nextchar = (char *) "";
      optind++;
      return BAD_OPTION;
    }
    }

  /* Look at and handle the next option-character.  */

  {
    char c = *nextchar++;
    char *temp = my_index (optstring, c);

    /* Increment `optind' when we start to process its last character.  */
    if (*nextchar == '\0')
      ++optind;

    if (temp == NULL || c == ':')
      {
    if (opterr)
      {
#if 0
        if (c < 040 || c >= 0177)
          fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
               argv[0], c);
        else
          fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
#else
        /* 1003.2 specifies the format of this message.  */
        fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
#endif
      }
    optopt = c;
    return BAD_OPTION;
      }
    if (temp[1] == ':')
      {
    if (temp[2] == ':')
      {
        /* This is an option that accepts an argument optionally.  */
        if (*nextchar != '\0')
          {
        optarg = nextchar;
        optind++;
          }
        else
          optarg = 0;
        nextchar = NULL;
      }
    else
      {
        /* This is an option that requires an argument.  */
        if (*nextchar != '\0')
          {
        optarg = nextchar;
        /* If we end this ARGV-element by taking the rest as an arg,
           we must advance to the next element now.  */
        optind++;
          }
        else if (optind == argc)
          {
        if (opterr)
          {
#if 0
            fprintf (stderr, "%s: option `-%c' requires an argument\n",
                 argv[0], c);
#else
            /* 1003.2 specifies the format of this message.  */
            fprintf (stderr, "%s: option requires an argument -- %c\n",
                 argv[0], c);
#endif
          }
        optopt = c;
        if (optstring[0] == ':')
          c = ':';
        else
          c = BAD_OPTION;
          }
        else
          /* We already incremented `optind' once;
         increment it again when taking next ARGV-elt as argument.  */
          optarg = argv[optind++];
        nextchar = NULL;
      }
      }
    return c;
  }
}

int
getopt (argc, argv, optstring)
     int argc;
     char *const *argv;
     const char *optstring;
{
  return _getopt_internal (argc, argv, optstring,
               (const struct option *) 0,
               (int *) 0,
               0);
}

int
getopt_long (argc, argv, options, long_options, opt_index)
     int argc;
     char *const *argv;
     const char *options;
     const struct option *long_options;
     int *opt_index;
{
  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
}

#endif  /* _LIBC or not __GNU_LIBRARY__.  */

#ifdef TEST

/* Compile with -DTEST to make an executable for use in testing
   the above definition of `getopt'.  */

int
main (argc, argv)
     int argc;
     char **argv;
{
  int c;
  int digit_optind = 0;

  while (1)
    {
      int this_option_optind = optind ? optind : 1;

      c = getopt (argc, argv, "abc:d:0123456789");
      if (c == EOF)
    break;

      switch (c)
    {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      if (digit_optind != 0 && digit_optind != this_option_optind)
        printf ("digits occur in two different argv-elements.\n");
      digit_optind = this_option_optind;
      printf ("option %c\n", c);
      break;

    case 'a':
      printf ("option a\n");
      break;

    case 'b':
      printf ("option b\n");
      break;

    case 'c':
      printf ("option c with value `%s'\n", optarg);
      break;

    case BAD_OPTION:
      break;

    default:
      printf ("?? getopt returned character code 0%o ??\n", c);
    }
    }

  if (optind < argc)
    {
      printf ("non-option ARGV-elements: ");
      while (optind < argc)
    printf ("%s ", argv[optind++]);
      printf ("\n");
    }

  exit (0);
}

#endif /* TEST */

A  => common/faad/getopt.h +130 -0
@@ 1,130 @@
/* Declarations for getopt.
   Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.

   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, 675 Mass Ave, Cambridge, MA 02139, USA.  */

#ifndef _GETOPT_H
#define _GETOPT_H 1

#ifdef  __cplusplus
extern "C" {
#endif

#ifndef __MacOSX__

/* For communication from `getopt' to the caller.
   When `getopt' finds an option that takes an argument,
   the argument value is returned here.
   Also, when `ordering' is RETURN_IN_ORDER,
   each non-option ARGV-element is returned here.  */

extern char *optarg;

/* Index in ARGV of the next element to be scanned.
   This is used for communication to and from the caller
   and for communication between successive calls to `getopt'.

   On entry to `getopt', zero means this is the first call; initialize.

   When `getopt' returns EOF, this is the index of the first of the
   non-option elements that the caller should itself scan.

   Otherwise, `optind' communicates from one call to the next
   how much of ARGV has been scanned so far.  */

extern int optind;

/* Callers store zero here to inhibit the error message `getopt' prints
   for unrecognized options.  */

extern int opterr;

/* Set to an option character which was unrecognized.  */

extern int optopt;
#endif

/* Describe the long-named options requested by the application.
   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
   of `struct option' terminated by an element containing a name which is
   zero.

   The field `has_arg' is:
   no_argument      (or 0) if the option does not take an argument,
   required_argument    (or 1) if the option requires an argument,
   optional_argument    (or 2) if the option takes an optional argument.

   If the field `flag' is not NULL, it points to a variable that is set
   to the value given in the field `val' when the option is found, but
   left unchanged if the option is not found.

   To have a long-named option do something other than set an `int' to
   a compiled-in constant, such as set a value from `optarg', set the
   option's `flag' field to zero and its `val' field to a nonzero
   value (the equivalent single-letter option character, if there is
   one).  For long options that have a zero `flag' field, `getopt'
   returns the contents of the `val' field.  */

struct option
{
#if __STDC__
  const char *name;
#else
  char *name;
#endif
  /* has_arg can't be an enum because some compilers complain about
     type mismatches in all the code that assumes it is an int.  */
  int has_arg;
  int *flag;
  int val;
};

/* Names for the values of the `has_arg' field of `struct option'.  */

#define no_argument     0
#define required_argument   1
#define optional_argument   2

//#if __STDC__ || defined(PROTO)
#if defined(__GNU_LIBRARY__)
/* Many other libraries have conflicting prototypes for getopt, with
   differences in the consts, in stdlib.h.  To avoid compilation
   errors, only prototype getopt for the GNU C library.  */
extern int getopt (int argc, char *const *argv, const char *shortopts);
#endif /* not __GNU_LIBRARY__ */
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
                const struct option *longopts, int *longind);
extern int getopt_long_only (int argc, char *const *argv,
                 const char *shortopts,
                     const struct option *longopts, int *longind);

/* Internal only.  Users should not call this directly.  */
extern int _getopt_internal (int argc, char *const *argv,
                 const char *shortopts,
                     const struct option *longopts, int *longind,
                 int long_only);
//#else /* not __STDC__ */
extern int getopt (int argc, char *const *argv, const char *shortopts);
//extern int getopt_long ();
//extern int getopt_long_only ();

//extern int _getopt_internal ();
//#endif /* not __STDC__ */

#ifdef  __cplusplus
}
#endif

#endif /* _GETOPT_H */

A  => common/faad/id3v2tag.c +1117 -0
@@ 1,1117 @@
/*
 * FAAD - Freeware Advanced Audio Decoder
 * Copyright (C) 2001 Menno Bakker
 *
 * 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 (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
 * 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
 *
 * $Id: id3v2tag.c,v 1.1 2002/01/14 19:15:49 menno Exp $
 */

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commctrl.h>
#include <resource.h>

#include <id3.h>

#include <id3v2tag.h>

HWND m_hwndList;

LPSTR ID3Frames[] =
{
    "No known frame",
    "Audio encryption",
    "Attached picture",
    "Comments",
    "Commercial frame",
    "Encryption method registration",
    "Equalization",
    "Event timing codes",
    "General encapsulated object",
    "Group identification registration",
    "Involved people list",
    "Linked information",
    "Music CD identifier",
    "MPEG location lookup table",
    "Ownership frame",
    "Private frame",
    "Play counter",
    "Popularimeter",
    "Position synchronisation frame",
    "Recommended buffer size",
    "Relative volume adjustment",
    "Reverb",
    "Synchronized lyric",
    "Synchronized tempo codes",
    "Album title",
    "BPM (beats per minute)",
    "Composer",
    "Genre", //"Content type",
    "Copyright message",
    "Date",
    "Playlist delay",
    "Encoded by",
    "Lyricist",
    "File type",
    "Time",
    "Content group description",
    "Title",
    "Subtitle",
    "Initial key",
    "Language(s)",
    "Length",
    "Media type",
    "Original album title",
    "Original filename",
    "Original lyricist(s)",
    "Original artist(s)",
    "Original release year",
    "File owner",
    "Lead performer(s)",
    "Band/orchestra/accompaniment",
    "Conductor/performer refinement",
    "Interpreted, remixed, or otherwise modified by",
    "Part of a set",
    "Publisher",
    "Track number",
    "Recording dates",
    "Internet radio station name",
    "Internet radio station owner",
    "Size",
    "ISRC (international standard recording code)",
    "Software/Hardware and settings used for encoding",
    "User defined text information",
    "Year",
    "Unique file identifier",
    "Terms of use",
    "Unsynchronized lyric",
    "Commercial information",
    "Copyright/Legal information",
    "Official audio file webpage",
    "Official artist webpage",
    "Official audio source webpage",
    "Official internet radio station homepage",
    "Payment",
    "Official publisher webpage",
    "User defined URL link",
    "Encrypted meta frame (id3v2.2.x)",
    "Compressed meta frame (id3v2.2.1)"
};

ID3GENRES ID3Genres[]=
{
    123,    "Acapella",
    34,     "Acid",
    74,     "Acid Jazz",
    73,     "Acid Punk",
    99,     "Acoustic",
    20,     "Alternative",
    40,     "AlternRock",
    26,     "Ambient",
    90,     "Avantgarde",
    116,    "Ballad",
    41,     "Bass",
    85,     "Bebob",
    96,     "Big Band",
    89,     "Bluegrass",
    0,      "Blues",
    107,    "Booty Bass",
    65,     "Cabaret",
    88,     "Celtic",
    104,    "Chamber Music",
    102,    "Chanson",
    97,     "Chorus",
    61,     "Christian Rap",
    1,      "Classic Rock",
    32,     "Classical",
    112,    "Club",
    57,     "Comedy",
    2,      "Country",
    58,     "Cult",
    3,      "Dance",
    125,    "Dance Hall",
    50,     "Darkwave",
    254,    "Data",
    22,     "Death Metal",
    4,      "Disco",
    55,     "Dream",
    122,    "Drum Solo",
    120,    "Duet",
    98,     "Easy Listening",
    52,     "Electronic",
    48,     "Ethnic",
    124,    "Euro-House",
    25,     "Euro-Techno",
    54,     "Eurodance",
    84,     "Fast Fusion",
    80,     "Folk",
    81,     "Folk-Rock",
    115,    "Folklore",
    119,    "Freestyle",
    5,      "Funk",
    30,     "Fusion",
    36,     "Game",
    59,     "Gangsta",
    38,     "Gospel",
    49,     "Gothic",
    91,     "Gothic Rock",
    6,      "Grunge",
    79,     "Hard Rock",
    7,      "Hip-Hop",
    35,     "House",
    100,    "Humour",
    19,     "Industrial",
    33,     "Instrumental",
    46,     "Instrumental Pop",
    47,     "Instrumental Rock",
    8,      "Jazz",
    29,     "Jazz+Funk",
    63,     "Jungle",
    86,     "Latin",
    71,     "Lo-Fi",
    45,     "Meditative",
    9,      "Metal",
    77,     "Musical",
    82,     "National Folk",
    64,     "Native American",
    10,     "New Age",
    66,     "New Wave",
    39,     "Noise",
    255,    "Not Set",
    11,     "Oldies",
    103,    "Opera",
    12,     "Other",
    75,     "Polka",
    13,     "Pop",
    62,     "Pop/Funk",
    53,     "Pop-Folk",
    109,    "Porn Groove",
    117,    "Power Ballad",
    23,     "Pranks",
    108,    "Primus",
    92,     "Progressive Rock",
    67,     "Psychadelic",
    93,     "Psychedelic Rock",
    43,     "Punk",
    121,    "Punk Rock",
    14,     "R&B",
    15,     "Rap",
    68,     "Rave",
    16,     "Reggae",
    76,     "Retro",
    87,     "Revival",
    118,    "Rhythmic Soul",
    17,     "Rock",
    78,     "Rock & Roll",
    114,    "Samba",
    110,    "Satire",
    69,     "Showtunes",
    21,     "Ska",
    111,    "Slow Jam",
    95,     "Slow Rock",
    105,    "Sonata",
    42,     "Soul",
    37,     "Sound Clip",
    24,     "Soundtrack",
    56,     "Southern Rock",
    44,     "Space",
    101,    "Speech",
    83,     "Swing",
    94,     "Symphonic Rock",
    106,    "Symphony",
    113,    "Tango",
    18,     "Techno",
    51,     "Techno-Industrial",
    60,     "Top 40",
    70,     "Trailer",
    31,     "Trance",
    72,     "Tribal",
    27,     "Trip-Hop",
    28,     "Vocal"
};

const int NUMFRAMES = sizeof(ID3Frames)/sizeof(ID3Frames[0]);
const int NUMGENRES = sizeof(ID3Genres)/sizeof(ID3Genres[0]);


LPSTR DupString(LPSTR lpsz)
{
    int cb = lstrlen(lpsz) + 1;
    LPSTR lpszNew = LocalAlloc(LMEM_FIXED, cb);
    if (lpszNew != NULL)
        CopyMemory(lpszNew, lpsz, cb);
    return lpszNew;
}

LPSTR GetFrameDesc(ID3_FrameID id)
{
    return DupString(ID3Frames[id]);
}

LPSTR GetGenre(LPSTR lpsz)
{
    int id = atoi(lpsz + 1);
    int i;

    if ((*(lpsz + 1) > '0') && (*(lpsz + 1) < '9'))
    {
        for (i = 0; i < NUMGENRES; i++)
        {
            if (id == ID3Genres[i].id)
                return DupString(ID3Genres[i].name);
        }
    }
    return DupString(lpsz);
}

void FillID3List(HWND hwndDlg, HWND hwndList, char *filename)
{
    ID3Tag *tag;
    ID3Frame *frame;
    ID3Field *field;
    ID3_FrameID eFrameID;
    char info[1024];
    int numFrames;
    int i;
    int iItem = 0;


    if ((tag = ID3Tag_New()) != NULL)
    {
        ID3Tag_Link(tag, filename);

        numFrames = ID3Tag_NumFrames(tag);

        for (i = 0; i < numFrames; i++)
        {
            iItem++;

            frame = ID3Tag_GetFrameNum(tag, i);
            eFrameID = ID3Frame_GetID(frame);

            switch (eFrameID)
            {
            case ID3FID_ALBUM:            case ID3FID_BPM:
            case ID3FID_COMPOSER:         case ID3FID_CONTENTTYPE:
            case ID3FID_COPYRIGHT:        case ID3FID_DATE:
            case ID3FID_PLAYLISTDELAY:    case ID3FID_ENCODEDBY:
            case ID3FID_LYRICIST:         case ID3FID_FILETYPE:
            case ID3FID_TIME:             case ID3FID_CONTENTGROUP:
            case ID3FID_TITLE:            case ID3FID_SUBTITLE:
            case ID3FID_INITIALKEY:       case ID3FID_LANGUAGE:
            case ID3FID_SONGLEN:          case ID3FID_MEDIATYPE:
            case ID3FID_ORIGALBUM:        case ID3FID_ORIGFILENAME:
            case ID3FID_ORIGLYRICIST:     case ID3FID_ORIGARTIST:
            case ID3FID_ORIGYEAR:         case ID3FID_FILEOWNER:
            case ID3FID_LEADARTIST:       case ID3FID_BAND:
            case ID3FID_CONDUCTOR:        case ID3FID_MIXARTIST:
            case ID3FID_PARTINSET:        case ID3FID_PUBLISHER:
            case ID3FID_TRACKNUM:         case ID3FID_RECORDINGDATES:
            case ID3FID_NETRADIOSTATION:  case ID3FID_NETRADIOOWNER:
            case ID3FID_SIZE:             case ID3FID_ISRC:
            case ID3FID_ENCODERSETTINGS:  case ID3FID_YEAR:
            {
                LV_ITEM lvi;
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));

                /* Initialize LV_ITEM members that are common to all items. */
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
                lvi.state = 0;
                lvi.stateMask = 0;
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
                lvi.iImage = 0;
                lvi.iItem = iItem;
                lvi.iSubItem = 0;

                pItem->frameId = eFrameID;
                pItem->aCols[0] = GetFrameDesc(eFrameID);

                field = ID3Frame_GetField(frame, ID3FN_TEXT);
                ID3Field_GetASCII(field, info, 1024, 1);
                if (eFrameID == ID3FID_CONTENTTYPE)
                    pItem->aCols[1] = GetGenre(info);
                else
                    pItem->aCols[1] = DupString(info);

                lvi.lParam = (LPARAM)pItem;    /* item data */

                /* Add the item. */
                ListView_InsertItem(hwndList, &lvi);

                break;
            }
            case ID3FID_USERTEXT:
            case ID3FID_COMMENT: /* Can also contain an extra language field (but not used now) */
            case ID3FID_UNSYNCEDLYRICS: /* Can also contain an extra language field (but not used now) */
            {
                LV_ITEM lvi;
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));

                /* Initialize LV_ITEM members that are common to all items. */
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
                lvi.state = 0;
                lvi.stateMask = 0;
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
                lvi.iImage = 0;
                lvi.iItem = iItem;
                lvi.iSubItem = 0;

                pItem->frameId = eFrameID;

                field = ID3Frame_GetField(frame, ID3FN_DESCRIPTION);
                ID3Field_GetASCII(field, info, 1024, 1);
                pItem->aCols[0] = DupString(info);

                field = ID3Frame_GetField(frame, ID3FN_TEXT);
                ID3Field_GetASCII(field, info, 1024, 1);
                pItem->aCols[1] = DupString(info);

                lvi.lParam = (LPARAM)pItem;    /* item data */

                /* Add the item. */
                ListView_InsertItem(hwndList, &lvi);

                break;
            }
            case ID3FID_WWWAUDIOFILE:       case ID3FID_WWWARTIST:
            case ID3FID_WWWAUDIOSOURCE:     case ID3FID_WWWCOMMERCIALINFO:
            case ID3FID_WWWCOPYRIGHT:       case ID3FID_WWWPUBLISHER:
            case ID3FID_WWWPAYMENT:         case ID3FID_WWWRADIOPAGE:
            {
                LV_ITEM lvi;
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));

                /* Initialize LV_ITEM members that are common to all items. */
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
                lvi.state = 0;
                lvi.stateMask = 0;
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
                lvi.iImage = 0;
                lvi.iItem = iItem;
                lvi.iSubItem = 0;

                pItem->frameId = eFrameID;

                pItem->aCols[0] = GetFrameDesc(eFrameID);

                field = ID3Frame_GetField(frame, ID3FN_URL);
                ID3Field_GetASCII(field, info, 1024, 1);
                pItem->aCols[1] = DupString(info);

                lvi.lParam = (LPARAM)pItem;    /* item data */

                /* Add the item. */
                ListView_InsertItem(hwndList, &lvi);

                break;
            }
            case ID3FID_WWWUSER:
            {
                LV_ITEM lvi;
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));

                /* Initialize LV_ITEM members that are common to all items. */
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
                lvi.state = 0;
                lvi.stateMask = 0;
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
                lvi.iImage = 0;
                lvi.iItem = iItem;
                lvi.iSubItem = 0;

                pItem->frameId = eFrameID;

                field = ID3Frame_GetField(frame, ID3FN_DESCRIPTION);
                ID3Field_GetASCII(field, info, 1024, 1);
                pItem->aCols[0] = DupString(info);

                field = ID3Frame_GetField(frame, ID3FN_URL);
                ID3Field_GetASCII(field, info, 1024, 1);
                pItem->aCols[1] = DupString(info);

                lvi.lParam = (LPARAM)pItem;    /* item data */

                /* Add the item. */
                ListView_InsertItem(hwndList, &lvi);

                break;
            }
            default:
                break;
            }
        }
        ID3Tag_Delete(tag);
    }
}

BOOL CALLBACK AddFrameProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    int i, cursel;

    switch (message) {
    case WM_INITDIALOG:
        EnableWindow(GetDlgItem(hwndDlg, IDC_COL0), FALSE);
        EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);

        /* Note: FRAMEID is the index in the combo box + 1 */
        for (i = 1; i < NUMFRAMES; i++)
        {
            SendMessage(GetDlgItem(hwndDlg, IDC_FRAMETYPE), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)ID3Frames[i]);
        }
        return TRUE;

    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case IDC_FRAMETYPE:
            if (HIWORD(wParam) == CBN_SELCHANGE)
            {
                cursel = SendMessage(GetDlgItem(hwndDlg, IDC_FRAMETYPE), CB_GETCURSEL, 0, 0);

                switch (cursel + 1)
                {
                case ID3FID_ALBUM:             case ID3FID_BPM:
                case ID3FID_COMPOSER:          case ID3FID_COPYRIGHT:
                case ID3FID_DATE:              case ID3FID_PLAYLISTDELAY:
                case ID3FID_ENCODEDBY:         case ID3FID_LYRICIST:
                case ID3FID_FILETYPE:          case ID3FID_TIME:
                case ID3FID_CONTENTGROUP:      case ID3FID_TITLE:
                case ID3FID_SUBTITLE:          case ID3FID_INITIALKEY:
                case ID3FID_LANGUAGE:          case ID3FID_SONGLEN:
                case ID3FID_MEDIATYPE:         case ID3FID_ORIGALBUM:
                case ID3FID_ORIGFILENAME:      case ID3FID_ORIGLYRICIST:
                case ID3FID_ORIGARTIST:        case ID3FID_ORIGYEAR:
                case ID3FID_FILEOWNER:         case ID3FID_LEADARTIST:
                case ID3FID_BAND:              case ID3FID_CONDUCTOR:
                case ID3FID_MIXARTIST:         case ID3FID_PARTINSET:
                case ID3FID_PUBLISHER:         case ID3FID_TRACKNUM:
                case ID3FID_RECORDINGDATES:    case ID3FID_NETRADIOSTATION:
                case ID3FID_NETRADIOOWNER:     case ID3FID_SIZE:
                case ID3FID_ISRC:              case ID3FID_ENCODERSETTINGS:
                case ID3FID_YEAR:              case ID3FID_WWWAUDIOFILE:
                case ID3FID_WWWARTIST:         case ID3FID_WWWAUDIOSOURCE:
                case ID3FID_WWWCOMMERCIALINFO: case ID3FID_WWWCOPYRIGHT:
                case ID3FID_WWWPUBLISHER:      case ID3FID_WWWPAYMENT:
                case ID3FID_WWWRADIOPAGE:      case ID3FID_CONTENTTYPE:
                {
                    SetDlgItemText(hwndDlg, IDC_COL0, ID3Frames[cursel+1]);
                    EnableWindow(GetDlgItem(hwndDlg, IDC_COL0), FALSE);
                    EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
                    break;
                }
                case ID3FID_USERTEXT:          case ID3FID_COMMENT:
                case ID3FID_UNSYNCEDLYRICS:    case ID3FID_WWWUSER:
                {
                    SetDlgItemText(hwndDlg, IDC_COL0, ID3Frames[cursel+1]);
                    EnableWindow(GetDlgItem(hwndDlg, IDC_COL0), TRUE);
                    EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
                    break;
                }
                default:
                    MessageBox(hwndDlg, "Sorry, this frame type cannot be added (yet).", "Sorry", MB_OK);
                    EnableWindow(GetDlgItem(hwndDlg, IDC_COL0), FALSE);
                    EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
                    break;
                }
            }
            return TRUE;
        case IDOK:
            {
                LV_ITEM lvi;
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
                char *col0 = LocalAlloc(LPTR, 1024);
                char *col1 = LocalAlloc(LPTR, 1024);

                /* Initialize LV_ITEM members that are common to all items. */
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
                lvi.state = 0;
                lvi.stateMask = 0;
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
                lvi.iImage = 0;
                lvi.iItem = ListView_GetItemCount(m_hwndList) + 1;
                lvi.iSubItem = 0;

                cursel = SendMessage(GetDlgItem(hwndDlg, IDC_FRAMETYPE), CB_GETCURSEL, 0, 0);
                pItem->frameId = cursel + 1;
                GetDlgItemText(hwndDlg, IDC_COL0, col0, 1024);
                GetDlgItemText(hwndDlg, IDC_COL1, col1, 1024);
                pItem->aCols[0] = col0;
                pItem->aCols[1] = col1;

                lvi.lParam = (LPARAM)pItem;    /* item data */

                /* Add the item. */
                ListView_InsertItem(m_hwndList, &lvi);
                ListView_Update(m_hwndList, lvi.iItem);
            }
        case IDCANCEL:
            EndDialog(hwndDlg, wParam);
            return TRUE;
        }
    }
    return FALSE;
}

BOOL List_AddFrame(HWND hwndApp, HWND hwndList)
{
    int result;

    m_hwndList = hwndList;

    result = DialogBox(hInstance_for_id3editor, MAKEINTRESOURCE(IDD_ADDFRAME),
        hwndApp, AddFrameProc);

    if (LOWORD(result) == IDOK)
        return TRUE;
    return FALSE;
}


void InsertTextFrame(HWND dlg, HWND list, int control, int item, int frame_id)
{
    LV_ITEM lvi;
    ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));

    /* Initialize LV_ITEM members that are common to all items. */
    lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
    lvi.state = 0;
    lvi.stateMask = 0;
    lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
    lvi.iImage = 0;
    lvi.iItem = item;
    lvi.iSubItem = 0;

    pItem->frameId = frame_id;
    pItem->aCols[0] = GetFrameDesc(frame_id);

    pItem->aCols[1] = LocalAlloc(LPTR, 1024);
    GetDlgItemText(dlg, control, pItem->aCols[1], 1024);

    lvi.lParam = (LPARAM)pItem;    /* item data */

    /* Add the item. */
    ListView_InsertItem(list, &lvi);
}

void AddFrameFromRAWData(HWND hwndList, int frameId, LPSTR data1, LPSTR data2)
{
    LV_ITEM lvi;
    ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
    int nextItem;

    nextItem = ListView_GetItemCount(hwndList);

    /* Initialize LV_ITEM members that are common to all items. */
    lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
    lvi.state = 0;
    lvi.stateMask = 0;
    lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
    lvi.iImage = 0;
    lvi.iItem = nextItem;
    lvi.iSubItem = 0;

    pItem->frameId = frameId;

    pItem->aCols[0] = LocalAlloc(LPTR, 1024);
    pItem->aCols[1] = LocalAlloc(LPTR, 1024);

    lstrcpy(pItem->aCols[0], data1);
    lstrcpy(pItem->aCols[1], data2);

    lvi.lParam = (LPARAM)pItem;    /* item data */

    /* Add the item. */
    ListView_InsertItem(hwndList, &lvi);
}

HWND m_hwndDlg;
int changed;

BOOL CALLBACK AddStandardProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    int added = 0;

    switch (message) {
    case WM_INITDIALOG:
        changed = 0;
        return TRUE;

    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case IDOK:
        {
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_TRACK)) > 0) {
                InsertTextFrame(hwndDlg, m_hwndList, IDC_TRACK, ListView_GetItemCount(m_hwndList)+1, ID3FID_TRACKNUM);
                added++;
            }

            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_TITLE)) > 0) {
                InsertTextFrame(hwndDlg, m_hwndList, IDC_TITLE, ListView_GetItemCount(m_hwndList)+1, ID3FID_TITLE);
                added++;
            }

            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ARTIST)) > 0) {
                InsertTextFrame(hwndDlg, m_hwndList, IDC_ARTIST, ListView_GetItemCount(m_hwndList)+1, ID3FID_LEADARTIST);
                added++;
            }

            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ALBUM)) > 0) {
                InsertTextFrame(hwndDlg, m_hwndList, IDC_ALBUM, ListView_GetItemCount(m_hwndList)+1, ID3FID_ALBUM);
                added++;
            }

            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_YEAR)) > 0) {
                InsertTextFrame(hwndDlg, m_hwndList, IDC_YEAR, ListView_GetItemCount(m_hwndList)+1, ID3FID_YEAR);
                added++;
            }

            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_GENRE)) > 0) {
                InsertTextFrame(hwndDlg, m_hwndList, IDC_GENRE, ListView_GetItemCount(m_hwndList)+1, ID3FID_CONTENTTYPE);
                added++;
            }

            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_COMMENT)) > 0) {
                InsertTextFrame(hwndDlg, m_hwndList, IDC_COMMENT, ListView_GetItemCount(m_hwndList)+1, ID3FID_COMMENT);
                added++;
            }

            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_COMPOSER)) > 0) {
                InsertTextFrame(hwndDlg, m_hwndList, IDC_COMPOSER, ListView_GetItemCount(m_hwndList)+1, ID3FID_COMPOSER);
                added++;
            }

            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ORIGARTIST)) > 0) {
                InsertTextFrame(hwndDlg, m_hwndList, IDC_ORIGARTIST, ListView_GetItemCount(m_hwndList)+1, ID3FID_ORIGARTIST);
                added++;
            }

            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_COPYRIGHT)) > 0) {
                InsertTextFrame(hwndDlg, m_hwndList, IDC_COPYRIGHT, ListView_GetItemCount(m_hwndList)+1, ID3FID_COPYRIGHT);
                added++;
            }

            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_URL)) > 0) {
                InsertTextFrame(hwndDlg, m_hwndList, IDC_URL, ListView_GetItemCount(m_hwndList)+1, ID3FID_WWWARTIST);
                added++;
            }

            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ENCBY)) > 0) {
                InsertTextFrame(hwndDlg, m_hwndList, IDC_ENCBY, ListView_GetItemCount(m_hwndList)+1, ID3FID_ENCODEDBY);
                added++;
            }

            if (added > 0)
                changed = 1;
        }
        case IDCANCEL:
            EndDialog(hwndDlg, changed);
            return TRUE;
        }
    }
    return FALSE;
}


BOOL List_AddStandardFrames(HWND hwndApp, HWND hwndList)
{
    int result;

    m_hwndList = hwndList;
    m_hwndDlg = hwndApp;

    result = DialogBox(hInstance_for_id3editor, MAKEINTRESOURCE(IDD_ADDSTANDARD),
        hwndApp, AddStandardProc);

    return result?TRUE:FALSE;
}


/* List_OnGetDispInfo - processes the LVN_GETDISPINFO  */
/*     notification message. */
/* pnmv - value of lParam (points to an LV_DISPINFO structure) */
void List_OnGetDispInfo(LV_DISPINFO *pnmv)
{
    /* Provide the item or subitem's text, if requested. */
    if (pnmv->item.mask & LVIF_TEXT) {
        ID3ITEM *pItem = (ID3ITEM *) (pnmv->item.lParam);
        lstrcpy(pnmv->item.pszText,
            pItem->aCols[pnmv->item.iSubItem]);
    }
}

ID3ITEM *pItem;
int editItemIndex;

BOOL CALLBACK EditTextFrameProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    LV_ITEM lvi;

    switch (message) {
    case WM_INITDIALOG:
        SetDlgItemText(hwndDlg, IDC_TEXTFRAMENAME, pItem->aCols[0]);
        SetDlgItemText(hwndDlg, IDC_EDITTEXTFRAME, pItem->aCols[1]);

        switch (pItem->frameId)
        {
        case ID3FID_ALBUM:              case ID3FID_BPM:
        case ID3FID_COMPOSER:           case ID3FID_COPYRIGHT:
        case ID3FID_DATE:               case ID3FID_PLAYLISTDELAY:
        case ID3FID_ENCODEDBY:          case ID3FID_LYRICIST:
        case ID3FID_FILETYPE:           case ID3FID_TIME:
        case ID3FID_CONTENTGROUP:       case ID3FID_TITLE:
        case ID3FID_SUBTITLE:           case ID3FID_INITIALKEY:
        case ID3FID_LANGUAGE:           case ID3FID_SONGLEN:
        case ID3FID_MEDIATYPE:          case ID3FID_ORIGALBUM:
        case ID3FID_ORIGFILENAME:       case ID3FID_ORIGLYRICIST:
        case ID3FID_ORIGARTIST:         case ID3FID_ORIGYEAR:
        case ID3FID_FILEOWNER:          case ID3FID_LEADARTIST:
        case ID3FID_BAND:               case ID3FID_CONDUCTOR:
        case ID3FID_MIXARTIST:          case ID3FID_PARTINSET:
        case ID3FID_PUBLISHER:          case ID3FID_TRACKNUM:
        case ID3FID_RECORDINGDATES:     case ID3FID_NETRADIOSTATION:
        case ID3FID_NETRADIOOWNER:      case ID3FID_SIZE:
        case ID3FID_ISRC:               case ID3FID_ENCODERSETTINGS:
        case ID3FID_YEAR:               case ID3FID_WWWAUDIOFILE:
        case ID3FID_WWWARTIST:          case ID3FID_WWWAUDIOSOURCE:
        case ID3FID_WWWCOMMERCIALINFO:  case ID3FID_WWWCOPYRIGHT:
        case ID3FID_WWWPUBLISHER:       case ID3FID_WWWPAYMENT:
        case ID3FID_WWWRADIOPAGE:       case ID3FID_CONTENTTYPE:
        {
            EnableWindow(GetDlgItem(hwndDlg, IDC_TEXTFRAMENAME), FALSE);
            EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTEXTFRAME), TRUE);
            break;
        }
        case ID3FID_USERTEXT:           case ID3FID_COMMENT:
        case ID3FID_UNSYNCEDLYRICS:     case ID3FID_WWWUSER:
        {
            EnableWindow(GetDlgItem(hwndDlg, IDC_TEXTFRAMENAME), TRUE);
            EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTEXTFRAME), TRUE);
            break;
        }
        default:
            EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
            EnableWindow(GetDlgItem(hwndDlg, IDC_TEXTFRAMENAME), FALSE);
            EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTEXTFRAME), FALSE);
            break;
        }
        return TRUE;

    case WM_COMMAND:
        switch (LOWORD(wParam)) {
        case IDOK:
        {
            GetDlgItemText(hwndDlg, IDC_TEXTFRAMENAME, pItem->aCols[0], 1024);
            GetDlgItemText(hwndDlg, IDC_EDITTEXTFRAME, pItem->aCols[1], 1024);
            lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
            lvi.state = 0;
            lvi.stateMask = 0;
            lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
            lvi.iImage = 0;
            lvi.iItem = editItemIndex;
            lvi.iSubItem = 0;
            lvi.lParam = (LPARAM)pItem;    /* item data */

            /* Add the item. */
            ListView_SetItem(m_hwndList, &lvi);
            ListView_Update(m_hwndList, editItemIndex);
        } /* Fall through */
        case IDCANCEL:
            EndDialog(hwndDlg, wParam);
            return TRUE;
        }
    }
    return FALSE;
}


/* Double clicking means editing a frame */
BOOL List_EditData(HWND hwndApp, HWND hwndList)
{
    LV_ITEM lvi;
    BOOL result;

    /* First get the selected item */
    int index = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);

    m_hwndList = hwndList;

    if (index != -1)
    {
        lvi.mask = LVIF_PARAM;
        lvi.iItem = index;
        lvi.iSubItem = 0;

        if (ListView_GetItem(hwndList, &lvi) == TRUE)
        {
            pItem = (ID3ITEM*)lvi.lParam;
            editItemIndex = lvi.iItem;

            result = DialogBox(hInstance_for_id3editor, MAKEINTRESOURCE(IDD_EDITTEXTFRAME),
                hwndApp, EditTextFrameProc);
            if (LOWORD(result) == IDOK)
                return TRUE;
        }
    }
    return FALSE;
}


/* Delete the selected frame */
BOOL List_DeleteSelected(HWND hwndApp, HWND hwndList)
{
    int items;

    /* First get the selected item */
    int index = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);

    if (index != -1)
        ListView_DeleteItem(hwndList, index);

    items = ListView_GetItemCount(hwndList);
    if (index != -1) return TRUE;
    else return FALSE;
}


/* Save the ID3 to the file */
void List_SaveID3(HWND hwndApp, HWND hwndList, char *filename)
{
    LV_ITEM lvi;
    ID3ITEM *pItem1;
    int i, items;
    ID3Tag *tag;
    ID3Frame *frame;
    ID3Field *field;
    
    /* Strip the tag first, before completely rewriting it */
    if ((tag = ID3Tag_New()) != NULL)
    {
        ID3Tag_Link(tag, filename);
        ID3Tag_Strip(tag, ID3TT_ALL);
        ID3Tag_Clear(tag);

        if (SendMessage(GetDlgItem(hwndApp, IDC_ID3V2TAG), BM_GETCHECK, 0, 0) == BST_UNCHECKED)
        {
            /* No frames saved */
            ID3Tag_Delete(tag);
            EnableWindow(GetDlgItem(hwndApp, IDC_ID3V2TAG), FALSE);
            ListView_DeleteAllItems(hwndList);
            return;
        }

        /* First get the number of items */
        items = ListView_GetItemCount(hwndList);

        if (items > 0)
        {
            for (i = 0; i < items; i++)
            {
                lvi.mask = LVIF_PARAM;
                lvi.iItem = i;
                lvi.iSubItem = 0;

                if (ListView_GetItem(hwndList, &lvi) == TRUE)
                {
                    pItem1 = (ID3ITEM*)lvi.lParam;

                    frame = ID3Frame_NewID(pItem1->frameId);

                    switch (pItem1->frameId)
                    {
                    case ID3FID_ALBUM:            case ID3FID_BPM:
                    case ID3FID_COMPOSER:         case ID3FID_CONTENTTYPE:
                    case ID3FID_COPYRIGHT:        case ID3FID_DATE:
                    case ID3FID_PLAYLISTDELAY:    case ID3FID_ENCODEDBY:
                    case ID3FID_LYRICIST:         case ID3FID_FILETYPE:
                    case ID3FID_TIME:             case ID3FID_CONTENTGROUP:
                    case ID3FID_TITLE:            case ID3FID_SUBTITLE:
                    case ID3FID_INITIALKEY:       case ID3FID_LANGUAGE:
                    case ID3FID_SONGLEN:          case ID3FID_MEDIATYPE:
                    case ID3FID_ORIGALBUM:        case ID3FID_ORIGFILENAME:
                    case ID3FID_ORIGLYRICIST:     case ID3FID_ORIGARTIST:
                    case ID3FID_ORIGYEAR:         case ID3FID_FILEOWNER:
                    case ID3FID_LEADARTIST:       case ID3FID_BAND:
                    case ID3FID_CONDUCTOR:        case ID3FID_MIXARTIST:
                    case ID3FID_PARTINSET:        case ID3FID_PUBLISHER:
                    case ID3FID_TRACKNUM:         case ID3FID_RECORDINGDATES:
                    case ID3FID_NETRADIOSTATION:  case ID3FID_NETRADIOOWNER:
                    case ID3FID_SIZE:             case ID3FID_ISRC:
                    case ID3FID_ENCODERSETTINGS:  case ID3FID_YEAR:
                    {
                        field = ID3Frame_GetField(frame, ID3FN_TEXT);
                        ID3Field_SetASCII(field, pItem1->aCols[1]);
                        ID3Tag_AddFrame(tag, frame);
                        break;
                    }
                    case ID3FID_USERTEXT:
                    case ID3FID_COMMENT: /* Can also contain an extra language field (but not used now) */
                    case ID3FID_UNSYNCEDLYRICS: /* Can also contain an extra language field (but not used now) */
                    {
                        field = ID3Frame_GetField(frame, ID3FN_DESCRIPTION);
                        ID3Field_SetASCII(field, pItem1->aCols[0]);
                        field = ID3Frame_GetField(frame, ID3FN_TEXT);
                        ID3Field_SetASCII(field, pItem1->aCols[1]);
                        ID3Tag_AddFrame(tag, frame);
                        break;
                    }
                    case ID3FID_WWWAUDIOFILE:     case ID3FID_WWWARTIST:
                    case ID3FID_WWWAUDIOSOURCE:   case ID3FID_WWWCOMMERCIALINFO:
                    case ID3FID_WWWCOPYRIGHT:     case ID3FID_WWWPUBLISHER:
                    case ID3FID_WWWPAYMENT:       case ID3FID_WWWRADIOPAGE:
                    {
                        field = ID3Frame_GetField(frame, ID3FN_URL);
                        ID3Field_SetASCII(field, pItem1->aCols[1]);
                        ID3Tag_AddFrame(tag, frame);
                        break;
                    }
                    case ID3FID_WWWUSER:
                    {
                        field = ID3Frame_GetField(frame, ID3FN_DESCRIPTION);
                        ID3Field_SetASCII(field, pItem1->aCols[0]);
                        field = ID3Frame_GetField(frame, ID3FN_URL);
                        ID3Field_SetASCII(field, pItem1->aCols[1]);
                        ID3Tag_AddFrame(tag, frame);
                        break;
                    }
                    default:
                        break;
                    }
                }
            }
            ID3Tag_UpdateByTagType(tag, ID3TT_ID3V2);
        }

        ID3Tag_Delete(tag);
    }
}

/* Get the title from the file */
void GetID3FileTitle(char *filename, char *title, char *format)
{
    ID3Tag *tag;
    ID3Frame *frame;
    ID3Field *field;
    char buffer[255];
    int some_info = 0;
    char *in = format;
    char *out = title;
    char *bound = out + (MAX_PATH - 10 - 1);


    if ((tag = ID3Tag_New()) != NULL)
    {
        ID3Tag_Link(tag, filename);

        while (*in && out < bound)
        {
            switch (*in) {
            case '%':
                ++in;
                break;

            default:
                *out++ = *in++;
                continue;
            }

            /* handle % escape sequence */
            switch (*in++) {
            case '0':
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_TRACKNUM)) != NULL) {
                    int size;
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
                    lstrcpy(out, buffer); out += size;
                    some_info = 1;
                }
                break;
            case '1':
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_LEADARTIST)) != NULL) {
                    int size;
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
                    lstrcpy(out, buffer); out += size;
                    some_info = 1;
                }
                break;
            case '2':
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_TITLE)) != NULL) {
                    int size;
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
                    lstrcpy(out, buffer); out += size;
                    some_info = 1;
                }
                break;
            case '3':
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_ALBUM)) != NULL) {
                    int size;
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
                    lstrcpy(out, buffer); out += size;
                    some_info = 1;
                }
                break;
            case '4':
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_YEAR)) != NULL) {
                    int size;
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
                    lstrcpy(out, buffer); out += size;
                    some_info = 1;
                }
                break;
            case '5':
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_COMMENT)) != NULL) {
                    int size;
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
                    lstrcpy(out, buffer); out += size;
                    some_info = 1;
                }
                break;
            case '6':
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_CONTENTTYPE)) != NULL) {
                    int size; char *tmp;
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
                    tmp = GetGenre(buffer);
                    lstrcpy(out, tmp); out += size;
                    some_info = 1;
                }
                break;
            case '7':
            {
                char *p=filename+lstrlen(filename);
                int len = 0;
                while (*p != '\\' && p >= filename) { p--; len++; }
                lstrcpy(out, ++p); out += len;
                some_info = 1;
                break;
            }
            }
        }

        ID3Tag_Delete(tag);
    }

    if (!some_info)
    {
        char *p=filename+lstrlen(filename);
        while (*p != '\\' && p >= filename) p--;
        lstrcpy(title,++p);
    }
}


A  => common/faad/id3v2tag.h +48 -0
@@ 1,48 @@
/*
 * FAAD - Freeware Advanced Audio Decoder
 * Copyright (C) 2001 Menno Bakker
 *
 * 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 (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
 * 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
 *
 * $Id: id3v2tag.h,v 1.1 2002/01/14 19:15:49 menno Exp $
 */

#ifndef __ID3V2TAG_H__
#define __ID3V2TAG_H__

void GetID3FileTitle(char *filename, char *title, char *format);
void FillID3List(HWND hwndDlg, HWND hwndList, char *filename);
void List_OnGetDispInfo(LV_DISPINFO *pnmv);
BOOL List_EditData(HWND hwndApp, HWND hwndList);
void List_SaveID3(HWND hwndApp, HWND hwndList, char *filename);
BOOL List_DeleteSelected(HWND hwndApp, HWND hwndList);
BOOL List_AddFrame(HWND hwndApp, HWND hwndList);
BOOL List_AddStandardFrames(HWND hwndApp, HWND hwndList);
void AddFrameFromRAWData(HWND hwndList, int frameId, LPSTR data1, LPSTR data2);

HINSTANCE hInstance_for_id3editor;

typedef struct ID3GENRES_TAG
{
    BYTE id;
    char name[30];
} ID3GENRES;

typedef struct id3item_tag {
    int frameId;
    LPSTR aCols[2];
} ID3ITEM;

#endif
\ No newline at end of file

A  => common/libsndfile/AUTHORS +17 -0
@@ 1,17 @@
The main author of libsndfile is Erik de Castro Lopo <erikd AT zip DOT com DOT au>.

The code in the src/GSM610 directory was written by Jutta Degener 
<jutta AT cs DOT tu-berlin DOT de> and Carsten Bormann 
<cabo AT cs DOT tu-berlin DOT de>. They should not be contacted in relation to 
libsndfile or the GSM 6.10 code that is part of libsndfile. Their original code 
can be found at:

    http://kbs.cs.tu-berlin.de/~jutta/toast.html

Code in the src/G72x directory was released by Sun Microsystems, Inc. to the 
public domain. Minor modifications were required to integrate these files 
into libsndfile. The changes are listed in src/G72x/ChangeLog.





A  => common/libsndfile/COPYING +503 -0
@@ 1,503 @@
                  GNU LESSER GENERAL PUBLIC LICENSE
                       Version 2.1, February 1999

 Copyright (C) 1991, 1999 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.

[This is the first released version of the Lesser GPL.  It also counts
 as the successor of the GNU Library Public License, version 2, hence
 the version number 2.1.]

                            Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.

  This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it.  You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.

  When we speak of free software, we are referring to freedom of use,
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 and use pieces of
it in new free programs; and that you are informed that you can do
these things.

  To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights.  These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.

  For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you.  You must make sure that they, too, receive or can get the source
code.  If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it.  And you must show them these terms so they know their rights.

  We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.

  To protect each distributor, we want to make it very clear that
there is no warranty for the free library.  Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.

  Finally, software patents pose a constant threat to the existence of
any free program.  We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder.  Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.

  Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License.  This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License.  We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.

  When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library.  The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom.  The Lesser General
Public License permits more lax criteria for linking other code with
the library.

  We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License.  It also provides other free software developers Less
of an advantage over competing non-free programs.  These disadvantages
are the reason we use the ordinary General Public License for many
libraries.  However, the Lesser license provides advantages in certain
special circumstances.

  For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard.  To achieve this, non-free programs must be
allowed to use the library.  A more frequent case is that a free
library does the same job as widely used non-free libraries.  In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.

  In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software.  For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.

  Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.

  The precise terms and conditions for copying, distribution and
modification follow.  Pay close attention to the difference between a
"work based on the library" and a "work that uses the library".  The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.

                  GNU LESSER GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".

  A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.

  The "Library", below, refers to any such software library or work
which has been distributed under these terms.  A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language.  (Hereinafter, translation is
included without limitation in the term "modification".)

  "Source code" for a work means the preferred form of the work for
making modifications to it.  For a library, 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 library.

  Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it).  Whether that is true depends on what the Library does
and what the program that uses the Library does.
  
  1. You may copy and distribute verbatim copies of the Library's
complete 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 distribute a copy of this License along with the
Library.

  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 Library or any portion
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.

    b) You must cause the files modified to carry prominent notices
    stating that you changed the files and the date of any change.

    c) You must cause the whole of the work to be licensed at no
    charge to all third parties under the terms of this License.

    d) If a facility in the modified Library refers to a function or a
    table of data to be supplied by an application program that uses
    the facility, other than as an argument passed when the facility
    is invoked, then you must make a good faith effort to ensure that,
    in the event an application does not supply such function or
    table, the facility still operates, and performs whatever part of
    its purpose remains meaningful.

    (For example, a function in a library to compute square roots has
    a purpose that is entirely well-defined independent of the
    application.  Therefore, Subsection 2d requires that any
    application-supplied function or table used by this function must
    be optional: if the application does not supply it, the square
    root function must still compute square roots.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Library,
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 Library, 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 Library.

In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library.  To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License.  (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.)  Do not make any other change in
these notices.

  Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.

  This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.

  4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you 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.

  If distribution of 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 satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.

  5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library".  Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.

  However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library".  The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.

  When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library.  The
threshold for this to be true is not precisely defined by law.

  If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work.  (Executables containing this object code plus portions of the
Library will still fall under Section 6.)

  Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.

  6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.

  You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License.  You must supply a copy of this License.  If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License.  Also, you must do one
of these things:

    a) Accompany the work with the complete corresponding
    machine-readable source code for the Library including whatever
    changes were used in the work (which must be distributed under
    Sections 1 and 2 above); and, if the work is an executable linked
    with the Library, with the complete machine-readable "work that
    uses the Library", as object code and/or source code, so that the
    user can modify the Library and then relink to produce a modified
    executable containing the modified Library.  (It is understood
    that the user who changes the contents of definitions files in the
    Library will not necessarily be able to recompile the application
    to use the modified definitions.)

    b) Use a suitable shared library mechanism for linking with the
    Library.  A suitable mechanism is one that (1) uses at run time a
    copy of the library already present on the user's computer system,
    rather than copying library functions into the executable, and (2)
    will operate properly with a modified version of the library, if
    the user installs one, as long as the modified version is
    interface-compatible with the version that the work was made with.

    c) Accompany the work with a written offer, valid for at
    least three years, to give the same user the materials
    specified in Subsection 6a, above, for a charge no more
    than the cost of performing this distribution.

    d) If distribution of the work is made by offering access to copy
    from a designated place, offer equivalent access to copy the above
    specified materials from the same place.

    e) Verify that the user has already received a copy of these
    materials or that you have already sent this user a copy.

  For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it.  However, as a special exception,
the materials to be 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.

  It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system.  Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.

  7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:

    a) Accompany the combined library with a copy of the same work
    based on the Library, uncombined with any other library
    facilities.  This must be distributed under the terms of the
    Sections above.

    b) Give prominent notice with the combined library of the fact
    that part of it is a work based on the Library, and explaining
    where to find the accompanying uncombined form of the same work.

  8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License.  Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library 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.

  9. 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 Library or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.

  10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
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 with
this License.

  11. 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 Library at all.  For example, if a patent
license would not permit royalty-free redistribution of the Library 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 Library.

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.

  12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library 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.

  13. The Free Software Foundation may publish revised and/or new
versions of the Lesser 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 Library
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 Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.

  14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
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

  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "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
LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. 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 LIBRARY 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
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries

  If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change.  You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).

  To apply these terms, attach the following notices to the library.  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 library's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    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 (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
    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

Also add information on how to contact you by electronic and paper mail.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the
  library `Frob' (a library for tweaking knobs) written by James Random Hacker.

  <signature of Ty Coon>, 1 April 1990
  Ty Coon, President of Vice

That's all there is to it!


A  => common/libsndfile/ChangeLog +1202 -0
@@ 1,1202 @@
2001-11-11  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

	* examples/sfplay_beos.cpp
	Added BeOS version of sfplay.c. This needs to be compiled using a C++
	compiler so is therefore not built by default. Thanks to Marcus Overhagen
	for providing this.

2001-11-11  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

	* src/*.[ch]
	Removed all usage of off_t which is not part of the ISO C standard. All places 
	which were using it are now using type long which is the type of the offset 
	parameter for the fseek function.
	This should fix problems on BeOS, MacOS and *BSD like systems which were failing
	"make check" because sizeof (long) != sizeof (off_t).

2001-11-10  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

	* examples/sfplay.c
	New example file showing how libsndfile can be used to read and play a sound file.
	At the moment on Linux is supported. Others will follow in the near future.

2001-11-08  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/au.c src/sndfile.au
	Added support for 32 bit float data in big and little endian AU files.
	
	* tests/write_read_test.c
	Added tests for 32 bit float data in AU files.

2001-11-06  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * tests/lossy_comp_test.c
	Finalised testing of stereo files where possible.

2001-11-05  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/wav_ms_adpcm.c
	Fixed bug in writing stereo MS ADPCM WAV files. Thanks to Xu Xin for pointing
	out this problem.

2001-10-24  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/wav_ms_adpcm.c
	Modified function srate2blocksize () to handle 44k1Hz stereo files.

2001-10-24  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * tests/lossy_comp_test.c
	Modified this test program so that for stereo capable files, test stereo mode 
	instead of mono.

2001-10-06  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/common.h 
    Win32 has _snprintf and _vsnprintf but not snprintf and vsnprintf. Added a
	conditional #define to fix this.

2001-10-04  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/voc.c
    Changed the TYPE_xxx enum names to VOC_TYPE_xxx to prevent name clashes
    on MacOS with CodeWarrior 6.0.

    * MacOS/MacOS-readme.txt 
    Updated the compile instructions. Probably still need work as I don't have
    access to a Mac.

2001-10-01  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/wav.c src/aiff.c common.c
    Changed all references to snprintf to LSF_SNPRINTF and all vsnprintf to 
    LSF_VSNPRINTF. LSF_VSNPRINTF and LSF_VSNPRINTF are defined in common.h.

    * src/common.h
    Added checking of HAVE_SNPRINTF and HAVE_VSNPRINTF and defining LSF_VSNPRINTF 
    and LSF_VSNPRINTF to appropriate values.

    * src/missing.c
    New file containing a minimal implementation of snprintf and vsnprintf functions 
    named missing_snprintf and missing_vsnprintf respectively. These are only 
    compliled into the binary if snprintf and/or vsnprintf are not available.

2001-09-29  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/ircam.c 
    New file to handle Berkeley/IRCAM/CARL files.

    * src/sndfile.c src/common.h
    Modified for IRCAM handling.

    * tests/*.c
    Added tests for IRCAM files.

2001-09-27  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/wav.c
    Apparently microsoft windows (tm) doesn't like ulaw and Alaw WAV files with 
    20 byte format chunks (contrary to ms's own documentation). Fixed the WAV 
    header writing code to generate smaller ms compliant ulaw and Alaw WAV files.

2001-09-17  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * tests/stdio_test.sh tests/stdio_test.c
    Shell script was rewritten as a C program due to incompatibilities of the sh
    shell on Linux and Solaris.

2001-09-16  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * tests/stdio_test.sh tests/stdout_test.c tests/stdin_test.c
    New test programs to verify the correct operation of reading from stdin and 
    writing to stdout.

    * src/sndfile.c wav.c au.c nist.c paf.c
    Fixed a bugs uncovered by the new test programs above.

2001-09-15  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.c wav.c
    Fixed a bug preventing reading a file from stdin. Found by T. Narita.

2001-09-12  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/common.h
    Fixed a problem on OpenBSD 2.9 which was causing sf_seek() to fail on IMA WAV
    files. Root cause was the declaration of the func_seek typedef not matching the 
    functions it was actually being used to point to. In OpenBSD sizeof (off_t) != 
    sizeof (int). Thanks to Heikki Korpela for allowing me to log into his OpenBSD
    machine to debug this problem.

2001-09-03  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.c 
    Implemented sf_command ("norm float").

    * src/*.c
    Implemented handling of sf_command ("norm float"). Float normalization can now
    be turned on and off.

    * tests/double_test.c
    Renamed to floating_point_test.c. Modified to include tests for all scaled reads 
    and writes of floats and doubles.

    * src/au_g72x.c
    Fixed bug in normalization code found with improved floating_point_test program.

    * src/wav.c
    Added code for parsing 'INFO' and 'LIST' chunks. Will be used for extract text 
    annotations from WAV files.

    * src/aiff.c
    Added code for parsing '(c) ' and 'ANNO' chunks. Will be used for extract text 
    annotations from WAV files.

2001-09-02  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * examples/sf_info.c example/Makefile.am
    Renamed to sndfile_info.c. The program sndfile_info will now be installed when the 
    library is installed.

    * src/floatcast.h
    New file defining floating point to short and int casts. These casts will
    eventually replace all flot and double casts to short and int. See comments at
    the top of the file for the reasoning.
    
    * src/*.c
    Changed all default float and double casts to short or int with macros defined
    in floatcast.h. At the moment these casts do nothing. They will be replaced 
    with faster float to int cast operations in the near future.

2001-08-31  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>
    
    * tests/command_test.c
    New file for testing sf_command () functionality.

    * src/sndfile.c
    Revisiting of error return values of some functions.
    Started implementing sf_command () a new function will allow on-the-fly modification
    of library behaviour, or instance, sample value scaling.

    * src/common.h
    Added hook for format specific sf_command () calls to SNDFILE struct.
    
    * doc/api.html
    Updated and errors corrected.
    
    * doc/command.html
    New documentation file explaining new sf_command () function.

2001-08-11  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>
    
    * src/sndfile.c
    Fixed error return values from sf_read*() and sf_write*(). There were numerous
    instances of -1 being returned through size_t. These now all set error int the
    SF_PRIVATE struct and return 0. Thanks to David Viens for spotting this.

2001-08-01  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>
    
    * src/common.c
    Fixed use of va_arg() calls that were causing warning messages with the latest
    version of gcc (thanks Maurizio Umberto Puxeddu).

2001-07-25  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>
    
    * src/*.c src/sfendian.h 
    Moved definition of MAKE_MARKER macro to sfendian.h

2001-07-23  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>
    
    * src/sndfile.c
    Modified sf_get_lib_version () so that version string will be visible using the
    Unix strings command.

    * examples/Makefile.am examples/sfinfo.c
    Renamed sfinfo program and source code to sf_info. This prevents a name clash
    with the program included with libaudiofile.

2001-07-22  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * tests/read_seek_test.c tests/lossy_comp_test.c
    Added tests for sf_read_float () and sf_readf_float ().

    * src/voc.c
    New files for handling Creative Voice files (not complete).

    * src/samplitude.c
    New files for handling Samplitude files (not complete).
 
2001-07-21  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/aiff.c src/au.c src/paf.c src/svx.c src/wav.c
    Converted these files to using psf_binheader_readf() function. Will soon be ready
    to make reading writing from pipes work reliably.

    * src/*.[ch]
    Added code for sf_read_float () and sf_readf_float () methods of accessing 
    file data.
    
2001-07-20  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/paf.c src/wav_gsm610.c
    Removed two printf()s which had escaped notice for some time (thanks Sigbj�rn 
    Skj�ret).

2001-07-19  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/wav_gsm610.c
    Fixed a bug which prevented GSM 6.10 encoded WAV files generated by libsndfile from 
    being played in Windoze (thanks klay).

2001-07-18  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/common.[ch]
    Implemented psf_binheader_readf() which will do for file header reading what
    psf_binheader_writef() did for writing headers. Will eventually allow
    libsndfile to read and write from pipes, including named pipes.

2001-07-16  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * MacOS/config.h Win32/config.h
    Attempted to bring these two files uptodate with src/config.h. As I don't have
    access to either of these systems support for them may be completely broken.

2001-06-18  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/float32.c
    Fixed bug for big endian processors that can't read 32 bit IEEE floats. Now tested 
    on Intel x86 and UltraSparc processors.

2001-06-13  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/aiff.c
    Modified to allow REX files (from Propellorhead's Recycle and Reason programs) to 
    be read.
    REX files are basically an AIFF file with slightly unusual sequence of chunks
    (AIFF files are supposed to allow any sequence) and some extra  application 
    specific information. 
    Not yet able to write a REX file as the details of the application specific
    data is unknown.

2001-06-12  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/wav.c
    Fixed endian bug when reading PEAK chunk on big endian machines.

    * src/common.c
    Fixed endian bug when reading PEAK chunk on big endian machines with 
    --enable-force-broken-float configure option.
    Fix psf_binheader_writef for (FORCE_BROKEN_FLOAT ||______)

2001-06-07  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * configure.in src/config.h.in
    Removed old CAN_READ_WRITE_x86_IEEE configure variable now that float capabilities
    are detected at run time.
    Added FORCE_BROKEN_FLOAT to allow testing of broken float code on machines where
    the processor can in fact handle floats correctly. 
    
    * src/float32.c
    Rejigged code reading and writing of floats on broken processors.
    
    * m4/
    Removed this directory and all its files as they are no longer needed.

2001-06-05  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * tests/peak_chunk_test.c
    New test to validate reading and writing of peak chunk.
    
    * examples/sfconvert
    Added -float32 option.

    * src/*.c
    Changed all error return values to negative values (ie the negative of what they
    were). 
    
    * src/sndfile.c tests/error_test.c
    Modified to take account of the previous change.

2001-06-04  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/float32.c
    File renamed from wav_float.c and renamed function to something more general.
    Added runtime detection of floating point capabilities. 
    Added recording of peaks during write for generation of PEAK chunk. 
    
    * src/wav.c src/aiff.c
    Added handing for PEAK chunk for floating point files. PEAK is read when the
    file headers are read and generated when the file is closed. Logic is in place
    for adding PEAK chunk to end of file when writing to a pipe (reading and writing 
    from/to pipe to be implemented soon).

    * src/sndfile.c
    Modified sf_signal_max () to use PEAK values if present.

2001-06-03  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/*.c
    Added pcm_read_init () and pcm_write_init () to src/pcm.c and removed all other calls
    to functions in this file from the filetype specific files.
    
    * src/*.c
    Added alaw_read_init (), alaw_write_int (), ulaw_read_init () and ulaw_write_init () 
    and removed all other calls to functions in alaw.c and ulaw.c from the filetype 
    specific files.
    
    * tests/write_read_test.c
    Added tests to validate sf_seek () on all file types.

    * src/raw.c
    Implemented raw_seek () function to fix a bug where sf_seek (file, 0, SEEK_SET) on a 
    RAW file failed.

    * src/paf.c
    Fixed a bug in paf24_seek () found due to added seeks tests in tests/write_read_test.c

2001-06-01  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * tests/read_seek_test.c
    Fixed a couple of broken binary files.

    * src/aiff.c src/wav.c
    Added handling of PEAK chunks on file read.

2001-05-31  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * check_libsndfile.py
    New file for the regression testing of libsndfile. 
    check_libsndfile.py is a Python script which reads in a file containing 
    filenames of audio files. Each file is checked by running the examples/sfinfo 
    program on them and checking for error or warning messages in the libsndfile 
    log buffer.

    * check_libsndfile.list
    This is an example list of audio files for use with check_libsndfile.py

    * tests/lossy_comp_test.c
    Changed the defined value of M_PI for math header files which don't have it.
    This fixed validation test failures on MetroWerks compilers. Thanks to Lord 
    Praetor Satanus of Acheron for bringing this to my attention.

2001-05-30  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/common.[ch]
    Removed psf_header_setf () which was no longer required after refactoring
    and simplification of header writing.
    Added 'z' format specifier to psf_binheader_writef () for zero filling header 
    with N bytes. Used by paf.c and nist.c

    * tests/check_log_buffer.c
    New file implementing check_log_buffer () which reads the log buffer of a SNDFILE*
    object and searches for error and warning messages. Calls exit () if any are found.

    * tests/*.c 
    Added calls to check_log_buffer () after each call to sf_open_XXX ().

2001-05-29  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/wav.c src/wav_ms_adpcm.c src/wav_gsm610.c
    Major rehack of header writing using psf_binheader_writef ().

2001-05-28  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/wav.c src/wav_ima_adpcm.c
    Major rehack of header writing using psf_binheader_writef ().

2001-05-27  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/wav.c
    Changed return type of get_encoding_str () to prevent compiler warnings on
    Mac OSX.

    * src/aiff.c src/au.c
    Major rehack of header writing using psf_binheader_writef ().

2001-05-25  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/common.h src/common.c
    Added comments.
    Name of log buffer changed from strbuffer to logbuffer.
    Name of log buffer index variable changed from strindex to logindex.

    * src/*.[ch]
    Changed name of internal logging function from psf_sprintf () to psf_log_printf ().
    Changed name of internal header generation functions from psf_[ab]h_printf () to 
    psf_asciiheader_printf () and psf_binheader_writef ().
    Changed name of internal header manipulation function psf_hsetf () to 
    psf_header_setf (). 

2001-05-24  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/nist.c
    Fixed reading and writing of sample_byte_format header. "01" means little endian 
    and "10" means big endian regardless of bit width.

    * configure.in
    Detect Mac OSX and disable -Wall and -pedantic gcc options. Mac OSX is way screwed
    up and spews out buckets of warning messages from the system headers.
    Added --disable-gcc-opt configure option (sets gcc optimisation to -O0 ) for 
    easier debugging.
    Made decision to harmonise source code version number and .so library version
    number. Future releases will stick to this rule.

    * doc/new_file_type.HOWTO
    New file to document the addition of new file types to libsndfile.

2001-05-23  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/nist.c
    New file for reading/writing Sphere NIST audio file format.
    Originally requested by Elis Pomales in 1999. 
    Retrieved from unstable (and untouched for 18 months) branch of libsndfile.
    Some vital information gleaned from the source code to Bill Schottstaedt's sndlib 
    library : ftp://ccrma-ftp.stanford.edu/pub/Lisp/sndlib.tar.gz
    Currently reading and writing 16, 24 and 32 bit, big-endian and little endian, 
    stereo and mono files. 

    * src/common.h src/common.c
    Added psf_ah_printf () function to help construction of ASCII headers (ie NIST).

    * configure.in
    Added test for vsnprintf () required by psf_ah_printf ().

    * tests/write_read_test.c
    Added tests for supported NIST files.

2001-05-22  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * tests/write_read_test.c
    Added tests for little endian AIFC files.

    * src/aiff.c
    Minor re-working of aiff_open_write ().
    Added write support for little endian PCM encoded AIFC files.

2001-05-13  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/aiff.c
    Minor re-working of aiff_open_read ().
    Added read support for little endian PCM encoded AIFC files from the Mac OSX CD ripper 
    program. Guillaume Lessard provided a couple of sample files and a working patch. 
    The patch was not used as is but gave a good guide as to what to do. 

2001-05-13  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/aiff.c
    Added support for little endian encoded AIFC files. Guillaume Lessard provided a couple
    of sample files and a working patch. The patch was not used as is but gave a good guide
    as to what to do. 

2001-05-11  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.h
    Fixed comments about endian-ness of WAV and AIFF files. Guillaume Lessard pointed 
    out the error.

2001-04-23  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * examples/make_sine.c
    Re-write of this example using sample rate and required frequency in Hz.

2001-02-11  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.c
    Fixed bug that prevented known file types from being read as RAW PCM data.

2000-12-16  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/aiff.c
    Added handing of COMT chunk.

2000-11-16  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * examples/sfconvert.c
    Fixed bug in normalisatio code. Pointed out by Johnny Wu.

2000-11-08  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * Win32/config.h
    Fixed the incorrect setting of HAVE_ENDIAN_H parameter. Win32 only issue.

2000-10-27  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * tests/Makefile.am
    Added -lm for write_read_test_LDADD.

2000-10-16  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.c src/au.c
    Fixed bug which prevented writing of G723 24kbps AU files.

    * tests/lossy_comp_test.c
    Corrrection to options for G723 tests.

    * configure.in
    Added --disable-gcc-pipe option for DJGPP compiler (gcc on MS-DOS) which 
    doesn't allow gcc -pipe option.

2000-09-03  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/ulaw.c src/alaw.c src/wav_imaadpcm.c src/msadpcm.c src/wav_gsm610.c
    Fixed normailsation bugs shown up by new double_test program.

2000-08-31  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/pcm.c
    Fixed bug in normalisation code (spotted by Steve Lhomme).

    * tests/double_test.c
    New file to test scaled and unscaled sf_read_double() and sf_write_double()
    functions.

2000-08-28  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * COPYING
    Changed to the LGPL COPYING file (spotted by H. S. Teoh).

2000-08-21  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.h
    Removed prototype of unimplemented function sf_get_info(). Added prototype for
    sf_error_number() Thanks to Sigbj�rn Skj�ret for spotting these.

2000-08-18  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/newpcm.h
    New file to contain a complete rewrite of the PCM data handling.

2000-08-15  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.c
    Fixed a leak of FILE* pointers in sf_open_write(). Thanks to Sigbj�rn Skj�ret
    for spotting this one.

2000-08-15  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.c
    Fixed a leak of FILE* pointers in sf_open_read(). Thanks to Sigbj�rn Skj�ret
    for spotting this one.

2000-08-13  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/au_g72x.c src/G72x/g72x.c
    Added G723 encoded AU file support.

    * tests/lossy_comp_test.c
    Added tests for G721 and G723 encoded AU files.

2000-08-06  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * all files
    Changed the license to LGPL. Albert Faber who had copyright on Win32/unistd.h
    gave his permission to change the license on that file. All other files were
    either copyright erikd AT zip DOT com DOT au or copyright under a GPL/LGPL compatible
    license.

2000-08-06  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * tests/lossy_comp_test.c
    Fixed incorrect error message.

    * src/au_g72x.c src/G72x/*
    G721 encoded AU files now working.

    * Win32/README-Win32.txt
    Replaced this file with a new one which gives a full explanation
    of how to build libsndfile under Win32. Thanks to Mike Ricos.

2000-08-05  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/*.[ch]
    Removed double leading underscores from the start of all variable and
    function names. Identifiers with a leading underscores are reserved
    for use by the compiler.

    * src/au_g72x.c src/G72x/*
    Continued work on G721 encoded AU files.

2000-07-12  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/G72x/*
    New files for reading/writing G721 and G723 ADPCM audio. These files 
    are from a Sun Microsystems reference implementation released under a 
    free software licence.
    Extensive changes to this code to make it fit in with libsndfile.
    See the ChangeLog in this directory for details.

    * src/au_g72x.c
    New file for G721 encoded AU files.

2000-07-08  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * libsndfile.spec.in
    Added a spec file for making RPMs. Thanks to Josh Green for supplying this.

2000-06-28  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.c src/sndfile.h
    Add checking for and handling of header-less u-law encoded AU/SND files.
    Any file with a ".au" or ".snd" file extension and without the normal
    AU file header is treated as an 8kHz, u-law encoded file.

    * src/au.h
    New function for opening a headerless u-law encoded file for read.

2000-06-04  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/paf.c
    Add checking for files shorter than minimal PAF file header length.

2000-06-02  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * tests/write_read_test.c
    Added extra sf_perror() calls when sf_write_XXXX fails.

2000-05-29  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/common.c
    Modified usage of va_arg() macro to work correctly on PowerPC 
    Linux. Thanks to Kyle Wheeler for giving me ssh access to his 
    machine while I was trying to track this down.

    * configure.in src/*.[ch]
    Sorted out some endian-ness issues brought up by PowerPC Linux.

    * tests/read_seek_test.c
    Added extra debugging for when tests fail.

2000-05-18  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/wav.c
    Fixed bug in GSM 6.10 handling for big-endian machines. Thanks
    to Sigbj�rn Skj�ret for reporting this.

2000-04-25  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.c src/wav.c src/wav_gsm610.c
    Finallised writing of GSM 6.10 WAV files.

    * tests/lossy_comp_test.c
    Wrote new test code for GSM 6.10 files. 

    * examples/sfinfo.c
    Fixed incorrect format in printf() statement.

2000-04-06  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.h.in
    Fixed comments about sf_perror () and sf_error_str ().

2000-03-14  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * configure.in
    Fixed --enable-justsrc option.

2000-03-07  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * wav.c
    Fixed checking of bytespersec field of header. Still some weirdness
    with some files.

2000-03-05  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * tests/lossy_comp_test.c
    Added option to test PCM WAV files (sanity check).
    Fixed bug in sf_seek() tests.

2000-02-29  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.c src/wav.c
    Minor changes to allow writing of GSM 6.10 WAV files.

2000-02-28  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * configure.in Makefile.am src/Makefile.am
    Finally got around to figuring out how to build a single library from 
    multiple source directories.
    Reading GSM 6.10 files now seems to work.

2000-01-03  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/wav.c
    Added more error reporting in read_fmt_chunk().

1999-12-21  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * examples/sfinfo.c
    Modified program to accept multiple filenames from the command line.

1999-11-27  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/wav_ima_adpcm.c
    Moved code around in preparation to adding ability to read/write IMA ADPCM
    encoded AIFF files.

1999-11-16  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/common.c
    Fixed put_int() and put_short() macros used by _psf_hprintf() which were 
    causing seg. faults on Sparc Solaris.

1999-11-15  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/common.c
    Added string.h to includes. Thanks to Sigbjxrn Skjfret.

    * src/svx.c
    Fixed __svx_close() function to ensure FORM and BODY chunks are correctly
    set.

1999-10-01  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/au.c
    Fixed handling of incorrect size field in AU header on read. Thanks to 
    Christoph Lauer for finding this problem.

1999-09-28  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/aiff.c
    Fixed a bug with incorrect SSND chunk length being written. This also lead
    to finding an minor error in AIFF header parsing. Thanks to Dan Timis for 
    pointing this out.

1999-09-24  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/paf.c
    Fixed a bug with reading and writing 24 bit stereo PAF files. This problem
    came to light when implementing tests for the new functions which operate
    in terms of frames rather than items.

1999-09-23  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.c
    Modified file type detection to use first 12 bytes of file rather than 
    file name extension. Required this because NIST files use the same 
    filename extension as Microsoft WAV files.

    * src/sndfile.c src/sndfile.h
    Added short, int and double read/write functions which work in frames rather 
    than items. This was originally suggested by Maurizio Umberto Puxeddu

1999-09-22  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/svx.c
    Finished off implementation of write using __psf_hprintf().

1999-09-21  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/common.h
    Added a buffer to SF_PRIVATE for writing the header. This is required
    to make generating headers for IFF/SVX files easier as well as making
    it easier to do re-write the headers which will be required when 
    sf_rewrite_header() is implemented.

    * src/common.c
    Implemented __psf_hprintf() function. This is an internal function
    which is documented briefly just above the code.

1999-09-05  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.c
    Fixed a bug in sf_write_raw() where it was returning incorrect values
    (thanks to Richard Dobson for finding this one). Must put in a test 
    routine for sf_read_raw and sf_write_raw.

    * src/aiff.c
    Fixed default FORMsize in __aiff_open_write ().

    * src/sndfile.c
    Added copy of filename to internal data structure. IFF/SVX files 
    contain a NAME header chunk. Both sf_open_read() and sf_open_write()
    copy the file name (less the leading path information) to the
    filename field.

    * src/svx.c
    Started implementing writing of files.

1999-08-04  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/svx.c
    New file for reading/writing 8SVX and 16SVX files.

    * src/sndfile.[ch] src/common.h
    Changes for SVX files.

    * src/aiff.c
    Fixed header parsing when unknown chunk is found.

1999-08-01  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/paf.c
    New file for reading/writing Ensoniq PARIS audio file format.

    * src/sndfile.[ch] src/common.h
    Changes for PAF files.

    * src/sndfile.[ch]
    Added stuff for sf_get_lib_version() function.


1999-07-31  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.h MacOS/config.h
    Fixed minor MacOS configuration issues.

1999-07-30  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * MacOS/
    Added a new directory for the MacOS config.h file and the
    readme file.

    * src/aiff.c
    Fixed calculation of datalength when reading SSND chunk. Thanks to
    Sigbj�rn Skj�ret for pointing out this error.

1999-07-29  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.c src/sndfile.h src/raw.c
    Further fixing of #includes for MacOS.

1999-07-25  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/wav.c src/aiff.c
    Added call to ferror () in main header parsing loop of __XXX_open_read
    functions. This should fix problems on platforms (MacOS, AmigaOS) where 
    fseek()ing or fread()ing beyond the end of the file puts the FILE*
    stream in an error state until clearerr() is called.

    * tests/write_read_test.c
    Added tests for RAW header-less PCM files.

    * src/common.h
    Moved definition of struct tribyte to pcm.c which is the only place
    which needs it.

    * src/pcm.c
    Modified all code which assumed sizeof (struct tribyte) == 3. This code
    did not work on MacOS. Thanks to Ben "Jacobs" for pointing this out.

    * src/au.c
    Removed <sys/stat.h> from list of #includes (not being used).

    * src/sndfile.c
    Added MacOS specific #ifdef to replace <sys/stat.h>.

    * src/sndfile.h
    Added MacOS specific #ifdef to replace <sys/stat.h>.

    * src/sndfile.h
    Added MacOS specific typedef for off_t.

    * MacOS-readme.txt
    New file with instructions for building libsndfile under MacOS. Thanks
    to Ben "Jacobs" for supplying these instructions.

1999-07-24  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * configure.in
    Removed sndfile.h from generated file list as there were no longer
    any autoconf substitutions being made.

    * src/raw.c
    New file for handling raw header-less PCM files. In order to open these
    for read, the user must specify format, pcmbitwidth and channels in the
    SF_INFO struct when calling sf_open_read ().

    * src/sndfile.c
    Added support for raw header-less PCM files.    

1999-07-22  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * examples/sfinfo.c
    Removed options so the sfinfo program always prints out all the information.

1999-07-19  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/alaw.c
    New file for A-law encoding (similar to u-law).

    * tests/alaw_test.c
    New test program to test the A-law encode/decode lookup tables.

    * tests/lossy_comp_test.c
    Added tests for a-law encoded WAV, AU and AULE files.

1999-07-18  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.c src/au.c
    Removed second "#include <unistd.h>". Thanks to Ben "Jacobs" for pointing
    this out.

1999-07-18  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * tests/ulaw_test.c
    New test program to test the u-law encode/decode lookup tables.

1999-07-16  Erik de Castro Lopo  <erikd AT zip DOT com DOT au>

    * src/sndfile.h