Index: /libmpc/branches/r2d/mppenc/CMakeLists.txt
===================================================================
--- /libmpc/branches/r2d/mppenc/CMakeLists.txt	(revision 133)
+++ /libmpc/branches/r2d/mppenc/CMakeLists.txt	(revision 133)
@@ -0,0 +1,3 @@
+add_definitions(-DMPP_ENCODER -DFAST_MATH -DCVD_FASTLOG)
+add_executable(mppenc analy_filter encode_sv7 huffsv7 profile stderr winmsg ans fastmath keyboard psy tags bitstream fft4g mppenc psy_tab tools cvd fft_routines pipeopen quant wave_in)
+target_link_libraries(mppenc m)
Index: /libmpc/branches/r2d/mppenc/Makefile.am
===================================================================
--- /libmpc/branches/r2d/mppenc/Makefile.am	(revision 133)
+++ /libmpc/branches/r2d/mppenc/Makefile.am	(revision 133)
@@ -0,0 +1,14 @@
+bin_PROGRAMS = mppenc
+
+
+# set the include path found by configure
+INCLUDES = -I$(top_srcdir)/libmpcenc -I$(top_srcdir)/libmpcpsy \
+	-I$(top_srcdir)/common $(all_includes)
+
+# the library search path.
+mppenc_LDFLAGS = $(all_libraries) 
+mppenc_SOURCES = keyboard.c mppenc.c pipeopen.c stderr.c tags.c wave_in.c \
+	winmsg.c
+mppenc_LDADD = $(top_builddir)/libmpcpsy/libmpcpsy.a \
+	$(top_builddir)/libmpcenc/libmpcenc.a -lm
+AM_CFLAGS = -DMPP_ENCODER=1 -DTRUE=1 -DFALSE=0
Index: /libmpc/branches/r2d/mppenc/config.h
===================================================================
--- /libmpc/branches/r2d/mppenc/config.h	(revision 133)
+++ /libmpc/branches/r2d/mppenc/config.h	(revision 133)
@@ -0,0 +1,52 @@
+/*
+ * Musepack audio compression
+ * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf
+ *
+ * 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
+ */
+
+/* Determine Endianess of the machine */
+
+#define HAVE_LITTLE_ENDIAN  1234
+#define HAVE_BIG_ENDIAN     4321
+
+#define ENDIAN              HAVE_LITTLE_ENDIAN
+
+
+/* Test the fast float-to-int rounding trick works */
+
+#define HAVE_IEEE754_FLOAT
+#define HAVE_IEEE754_DOUBLE
+
+
+/* Test the presence of a 80-bit floating point type for writing AIFF headers */
+
+#define HAVE_IEEE854_LONGDOUBLE
+
+
+/* parsed values from file "version" */
+
+#ifndef MPPDEC_VERSION
+# define MPPDEC_VERSION   "1.15v"
+#endif
+
+#define MPPDEC_BUILD  "--Alpha--"
+
+#define MPPENC_MAJOR 1
+#define MPPENC_MINOR 17
+#define MPPENC_IMPLEMENT 0
+#define MPPENC_BUILD 0
+
+/* end of config.h */
Index: /libmpc/branches/r2d/mppenc/keyboard.c
===================================================================
--- /libmpc/branches/r2d/mppenc/keyboard.c	(revision 133)
+++ /libmpc/branches/r2d/mppenc/keyboard.c	(revision 133)
@@ -0,0 +1,128 @@
+/*
+ *  Keyboard input functions
+ *
+ *  (C) Frank Klemm 2002. All rights reserved.
+ *
+ *  Principles:
+ *
+ *  History:
+ *    ca. 1998    created
+ *    2002
+ *
+ *  Global functions:
+ *    -
+ *
+ *  TODO:
+ *    -
+ */
+
+#include "mppenc.h"
+
+#if defined _WIN32  ||  defined __TURBOC__
+
+# include <conio.h>
+
+int
+WaitKey ( void )
+{
+    return getch ();
+}
+
+int
+CheckKeyKeep ( void )
+{
+    int  ch;
+
+    if ( !kbhit () )
+        return -1;
+
+    ch = getch ();
+    ungetch (ch);
+    return ch;
+}
+
+int
+CheckKey ( void )
+{
+    if ( !kbhit () )
+        return -1;
+
+    return getch ();
+}
+
+#else
+
+# ifdef USE_TERMIOS
+#  include <termios.h>
+
+static struct termios  stored_settings;
+
+static void
+echo_on ( void )
+{
+    tcsetattr ( 0, TCSANOW, &stored_settings );
+}
+
+static void
+echo_off ( void )
+{
+    struct termios  new_settings;
+
+    tcgetattr ( 0, &stored_settings );
+    new_settings = stored_settings;
+
+    new_settings.c_lflag     &= ~ECHO;
+    new_settings.c_lflag     &= ~ICANON;        // Disable canonical mode, and set buffer size to 1 byte
+    new_settings.c_cc[VTIME]  = 0;
+    new_settings.c_cc[VMIN]   = 1;
+
+    tcsetattr ( 0, TCSANOW, &new_settings );
+}
+
+# else
+#  define echo_off()  (void)0
+#  define echo_on()   (void)0
+# endif
+
+int
+WaitKey ( void )
+{
+    unsigned char  buff [1];
+    int            ret;
+
+    echo_off ();
+    ret = read ( 0, buff, 1 );
+    echo_on ();
+    return ret == 1  ?  buff[0]  :  -1;
+}
+
+int
+CheckKeyKeep ( void )
+{
+    struct timeval  tv = { 0, 0 };      // Do not wait at all, not even a microsecond
+    fd_set          read_fd;
+
+    FD_ZERO ( &read_fd );               // Must be done first to initialize read_fd
+    FD_SET ( 0, &read_fd );             // Makes select() ask if input is ready;  0 is file descriptor for stdin
+
+    if ( -1 == select ( 1,              // number of the largest fd to check + 1
+                        &read_fd,
+                        NULL,           // No writes
+                        NULL,           // No exceptions
+                        &tv ) )
+        return -1;                      // an error occured
+
+    return FD_ISSET (0, &read_fd)  ?  0xFF  :  -1;   // read_fd now holds a bit map of files that are readable. We test the entry for the standard input (file 0).
+}
+
+int
+CheckKey ( void )
+{
+    if ( CheckKeyKeep () < 0 )
+        return -1;
+    return WaitKey ();
+}
+
+#endif
+
+/* end of keyboard.c */
Index: /libmpc/branches/r2d/mppenc/mpp.h
===================================================================
--- /libmpc/branches/r2d/mppenc/mpp.h	(revision 133)
+++ /libmpc/branches/r2d/mppenc/mpp.h	(revision 133)
@@ -0,0 +1,194 @@
+/*
+ * Musepack audio compression
+ * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf
+ *
+ * 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
+ */
+
+/******************************************************
+ *                                                    *
+ *            Source Compile configuration            *
+ *                                                    *
+ ******************************************************/
+
+
+#if !defined(__APPLE__)
+// use optimized assembler routines for Pentium III/K6-2/Athlon (only 32 bit OS, Intel x86 and no MAKE_xxBITS)
+// you need the NASM assembler on your system, the program becomes a little bit larger and decoding
+// on AMD K6-2 (x3), AMD K6-III (x3), AMD Duron (x1.7), AMD Athlon (x1.7), Pentium III (x2) and Pentium 4 (x1.8) becomes faster
+#define USE_ASM
+
+// Open Sound System support (only Unix with OSS support)
+// If your Operating System supports the Open Sound System, you can output to /dev/dsp* and
+// instead of writing a file the program plays the file via this sound device.
+// on some systems you also must link the libossaudio library, so maybe you also must edit the Makefile
+#define USE_OSS_AUDIO
+
+// Enlightenment Sound Daemon support (only Unix with ESD support)
+// If your Operating System supports the Enlightenment Sound Daemon you can output to /dev/esd and
+// instead of writing a file the program plays the file via this sound device.
+// you also must link the libesd library, so maybe you also must edit the Makefile
+//#define USE_ESD_AUDIO
+
+#endif
+
+// native Sun Onboard-Audio support (only SunOS)
+// If you have a Sun Workstation with Onboard-Audio, you can output to /dev/audio and
+// instead of writing a file the program plays the file via this sound device.
+// Some machines lacking librt.a so you are unable to link a static executable with realtime-support.
+// Although you can still perfectly use the dynamic executable.
+//#define USE_SUN_AUDIO
+
+// Sound support for SGI Irix
+// If you have a SGI Workstation running IRIX, you can output to /dev/audio and
+// instead of writing a file the program plays the file via this sound device.
+//#define USE_IRIX_AUDIO
+
+// Audio support for Windows (WAVE OUT) (only Windows)
+// If you have a Windows based system and if you also want to play files directly instead of only writing audio files,
+// then define the next item
+#define USE_WIN_AUDIO
+
+// Buffersize for Windows Audio in 4.5 KByte units
+// Only needed for Windows+USE_WIN_AUDIO
+// Good values are 8...32 for fast machines and 128...512 for slow machines
+// large values decrease average performance a little bit, increase memory
+// consumption (1 Block = 4.5 KByte), but increase buffering, so it takes a
+// longer time to get a dropout. Note that I don't have a 486/80...133, so
+// I don't know anything about their performance.
+// (Attention: 512 = additional 2.3 MByte of memory)
+#define MAX_WAVEBLOCKS    40
+
+// increase priority if destination is an audio device
+// this increases the priority of the decoder when playing the file directly to a sound card to reduce/prevent
+// dropouts during the playback due to CPU time shortage
+#define USE_NICE
+
+// use realtime scheduling if destination is an audio device
+// This sets the program to real time priority when playing the file directly to a sound card.
+// Now it should be really difficult to get dropouts (file IO and other realtime programs are the remaining weak points)
+#define USE_REALTIME
+
+// use ANSI-Escape sequences to structure output
+#define USE_ANSI_ESCAPE
+
+// Use termios for reading values from keyboard without echo and ENTER
+#define USE_TERMIOS
+
+// if none of the next three macros MAKE_xxBIT is defined,
+// normal non-dithered and non-shaped 16 bit PCM output is generated
+
+// create 16 bit Output
+// output is 16 bit wide, you can also dither and noise shape
+//#define MAKE_16BIT
+
+// create 24 bit Output
+// output is 24 bit wide instead of 16 bit wide, you can also dither and noise shape
+//#define MAKE_24BIT
+
+// create 32 bit Output
+// output is 32 bit wide instead of 16 bit wide, you can also dither and noise shape
+//#define MAKE_32BIT
+
+// Select subset of function used for file I/O:
+//   1: ANSI via file pointer (FILE*)
+//   2: POSIX via file handle (int or HANDLE)
+//   3: POSIX like lowest level function of Turbo/Borland C
+//   4: WinAMP 3: running inside WinAMP
+// Try to use '2', if this doesn't work, try '1'. '3' is for Borland compilers.
+#ifndef FILEIO
+# if   defined MPP_ENCODER
+#  define FILEIO      1             // mppenc still uses buffered ANSI-I/O
+# elif defined MPP_DECODER
+#  define FILEIO      2
+# else
+#   error Neigher MPP_DECODER nor MPP_ENCODER is defined. Abort.
+# endif
+#endif
+
+// the POSIX function read() can return less bytes than requested not only at the end of the file.
+// if this happens, the following macro must be defined:
+#define HAVE_INCOMPLETE_READ
+
+// use a shorter Huffman_t  representation, may be faster
+// use for performance tuning
+#define USE_HUFF_PACK
+
+// use shorter representation for SCF_Index[][] and Res[], may be faster
+// use for performance tuning
+#define USE_ARRAY_PACK
+
+// use the System 5 timer for profiling
+// otherwise a special piece of code for Turbo-C is used or the Timestamp Counter on Intel IA32/gcc systems.
+// Both is highly non-portable. This solution is more portable (you only need a SYS 5 compatible system,
+// but also much much more inaccurate.
+//#define USE_SYSV_TIMER
+
+// do a memory shift every n subband samples, otherwise only increment pointer (6, 12, 18 and 36 are good values)
+// use for performance tuning
+#define VIRT_SHIFT    18
+
+// selects InputBuff size, size is 4 * 2^IBUFLOG2 bytes (11...14 are good values)
+// use for performance tuning
+// can also be used to eliminate disk performance issue while tuning the program
+// (set to a value, so the test cases are fully read before decoding
+#define IBUFLOG2      14
+
+// Dump contents of MPEGplus files (only for development), 0x00 no dump
+// Bit 0: maxband, Bit 1: msbits, Bit 2: allocation/resolution, Bit 3: SCF
+// Bit 4: Subsamples, Bit 5: Datenrate, Bit 6: Bitusage der Sektionen
+//#define DUMPSELECT    0xFF
+
+// 16 bit and 32 bit accesses must be aligned, otherwise a bus error occures.
+// try this if you get bus errors
+//#define MUST_ALIGNED
+
+// Experimental: use http/ftp streaming
+#define USE_HTTP
+
+// _use setargv module
+#define USE_ARGV
+
+
+// Use IPv4 and IPv6
+//#define USE_IPv4_6
+// Use only IPv6
+//#define USE_IPv6
+
+// compile StreamVersion 8 decoding (always disable, no usabiltity)
+// do not edit
+//#define USE_SV8
+
+// disables assert()
+// assert() is for development only and decreases speed and increases the size of the program
+#ifndef NDEBUG
+# define NDEBUG
+#endif
+
+// Some other tracing (only for development)
+// do not edit
+//#define DEBUG
+
+// Some tracings of popen()
+// do not edit
+//#define DEBUG2
+
+// activate simple profiler
+//#define PROFILE
+
+// make debug output in tags.c stfu
+#define STFU
+
+/* end of mpp.h */
Index: /libmpc/branches/r2d/mppenc/mppdec.h
===================================================================
--- /libmpc/branches/r2d/mppenc/mppdec.h	(revision 133)
+++ /libmpc/branches/r2d/mppenc/mppdec.h	(revision 133)
@@ -0,0 +1,1116 @@
+/*
+ * Musepack audio compression
+ * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf
+ *
+ * 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
+ */
+
+//// Macros typical for Compilers:
+//
+//  __TURBOC__          Turbo-C, Borland-C
+//  __BORLANDC__        Borland-C
+//  __ZTC__             Zortech-C
+//  _MSC_VER            Microsoft-C
+//  __EMX__             Eberhard Mattes EMX (GNU based)
+//  __GNUC__            GNU C based compiler (also Cygwin)
+//  __CYGWIN__          Cygnus Windows C-Compiler (GNU based)
+//  __APPLE_CC__        Apple GCC (GNU based)
+
+
+//// Macros typical for Operating Systems
+//
+//  __linux__           Linux
+//  __bsdi__            BSDi
+//  __FreeBSD__         FreeBSD
+//  __NetBSD__          NetBSD
+//  __OpenBSD__         OpenBSD
+//  __unix__            Unix ????????
+//  _WIN16              16 bit-Windows
+//  _WIN32              32 bit-Windows (WIN32 is wrong, not defined by not MSC) (also __GNUC__ + _WIN32 is possible)
+//  _HPUX_SOURCE        HP-UX
+//  __BEOS__            BeOS
+//  __APPLE__           Apple Mac OS X (only when using Apple GCC)
+//  ???????             MS-DOS and relatives
+
+
+//// Macros typical for special conformances
+//                      System 5 Release 4 (SVr4)
+//                      System 5 ID     (SVID)
+//                      POSIX 1.0
+//                      POSIX 1.0b
+//                      X/OPEN
+//                      BSD 4.3
+//                      BSD 4.4
+//                      ANSI
+
+
+// Macros to manipulate Sockets + Files in one, in (+0x4000)
+// output times TIME/TIME_T/DTIME
+
+#ifndef MPPDEC_MPPDEC_H
+#define MPPDEC_MPPDEC_H
+
+//// optimization/feature defines //////////////////////////////////
+#ifndef NOT_INCLUDE_CONFIG_H
+# include "config.h"
+#endif
+#include "./mpp.h"
+
+
+//// portable system includes //////////////////////////////////////
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.h>
+#include <math.h>
+
+
+//// system dependent system includes //////////////////////////////
+// low level I/O, where are prototypes and constants?
+#if   defined _WIN32  ||  defined __TURBOC__  ||  defined __ZTC__  ||  defined _MSC_VER
+# include <io.h>
+# include <fcntl.h>
+# include <time.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+#elif defined __unix__  ||  defined __linux__  ||  defined __APPLE__
+# include <fcntl.h>
+# include <unistd.h>
+# include <sys/time.h>
+# include <sys/ioctl.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+#else
+// .... add Includes for new Operating System here (with prefix: #elif defined)
+# include <fcntl.h>
+# include <unistd.h>
+# include <sys/ioctl.h>
+# include <sys/stat.h>
+#endif
+
+
+#if   defined __linux__
+#  include <fpu_control.h>
+#elif defined __FreeBSD__
+# include <machine/floatingpoint.h>
+#elif defined _MSC_VER
+# include <float.h>
+#endif
+
+
+#if defined _WIN32
+# undef USE_OSS_AUDIO
+# undef USE_ESD_AUDIO
+# undef USE_SUN_AUDIO
+#else
+# undef USE_WIN_AUDIO
+#endif
+
+#if defined __APPLE__
+# undef USE_OSS_AUDIO
+# undef USE_SUN_AUDIO
+# undef USE_WIN_AUDIO
+# undef USE_NICE
+# undef USE_REALTIME
+# undef USE_ASM
+# undef USE_ESD_AUDIO
+# define NO_DEV_AUDIO
+# undef ENDIAN
+# define ENDIAN HAVE_BIG_ENDIAN
+#endif
+
+#if defined __TURBOC__
+# undef USE_OSS_AUDIO
+# undef USE_ESD_AUDIO
+# undef USE_SUN_AUDIO
+# undef USE_NICE
+# undef USE_REALTIME
+#endif
+
+#if defined USE_DIET  ||  defined MAKE_24BIT  ||  defined MAKE_32BIT
+# undef USE_ESD_AUDIO
+#endif
+
+#if defined MAKE_16BIT  ||  defined MAKE_24BIT  ||  defined MAKE_32BIT
+# undef USE_ASM
+#endif
+
+#if INT_MAX < 2147483647L
+# undef USE_ASM
+#endif
+
+// sound card
+#if defined USE_OSS_AUDIO
+# include <sys/ioctl.h>
+# include <sys/time.h>
+# if   defined __linux__        // the standard is that this file is stored somewhere on the hard disk
+#  include <linux/soundcard.h>
+# elif defined __bsdi__
+#  include <sys/soundcard.h>
+# elif defined __FreeBSD__
+#  include <machine/soundcard.h>
+# elif defined __NetBSD__  ||  defined __OpenBSD__
+#  include <soundcard.h>
+# elif defined __APPLE__  &&  defined __MACH__
+#  include <pleasepatchheretherightpathofsoundcard.hforMacOSX/soundcard.h>
+# else
+#  include <pleasepatchheretherightpathof/soundcard.h>
+# endif
+#endif /* USE_OSS_AUDIO */
+
+#if defined USE_ESD_AUDIO
+# include <esd.h>
+#endif
+
+#if defined USE_SUN_AUDIO
+# include <sys/audioio.h>
+#endif
+
+#ifdef MPP_ENCODER
+# undef USE_HTTP
+#endif
+
+#ifdef USE_HTTP
+# ifdef _WIN32
+#  include <winsock2.h>
+# else
+#  include <sys/socket.h>
+# endif
+#endif
+
+#if   defined USE_WIN_AUDIO
+# include <windows.h>
+# define WINAUDIO_FD            ((FILE_T)-128)
+#elif defined USE_IRIX_AUDIO
+# define IRIXAUDIO_FD           ((FILE_T)-127)
+#endif
+#define  NULL_FD                ((FILE_T)-126)
+
+#if defined USE_NICE  &&  !defined _WIN32
+# include <sys/resource.h>
+#endif
+
+// scheduler stuff
+#if defined USE_REALTIME  &&  !defined _WIN32
+# include <sched.h>
+#endif
+
+#ifndef O_BINARY
+# ifdef _O_BINARY
+#  define O_BINARY              _O_BINARY
+# else
+#  define O_BINARY              0
+# endif
+#endif
+
+#if defined _WIN32  ||  defined __TURBOC__
+# define strncasecmp(__s1,__s2,__n) strnicmp ((__s1), (__s2), (__n))
+# define strcasecmp(__s1,__s2)      stricmp  ((__s1), (__s2))
+# define MKDIR(__dir,__attr)        mkdir ((__dir))
+#else
+# define MKDIR(__dir,__attr)        mkdir ((__dir), (__attr))
+#endif
+
+#if defined _WIN32
+# include <direct.h>
+# define snprintf                   _snprintf
+# define getcwd(__buff,__len)       _getcwd ((__buff), (__len))
+# define sleep(__sec)               Sleep ((__sec) * 1000)
+#endif
+
+#if defined _WIN32
+# define TIME_T                     long
+# define TIME(__x)                  time ( &(__x) )
+# define DTIME(__x,__y)             ( (double)(__y) - (__x) )
+#else
+# define TIME_T                     struct timeval
+# define TIME(__x)                  gettimeofday ( &(__x), NULL )
+# define DTIME(__x,__y)             ( ((double)(__y).tv_sec - (__x).tv_sec) + 1.e-6 * ((double)(__y).tv_usec - (__x).tv_usec) )
+#endif
+
+#if   defined __GNUC__
+# define inline                 __inline__
+# define restrict
+#elif defined _WIN32
+# define inline                 __inline
+# define restrict
+#else
+# define inline
+# define restrict
+#endif
+
+
+//// Binary/Low-Level-IO ///////////////////////////////////////////
+//
+// All file I/O is basicly handled via an ANSI file pointer (type: FILE*) in
+// FILEIO-Mode 1 and via a POSIX file descriptor (type: int) in
+// FILEIO-Mode 2 and 3.
+//
+// Some operations are only available via the POSIX interface (fcntl, setmode,
+// ...) so we need a function to get the file descriptor from a file pointer.
+// In FILEIO-Mode 2 and 3 this is a dummy function because we are always working
+// with these file descriptors.
+//
+
+#if  FILEIO == 1
+# if   defined __BORLANDC__  ||  defined _WIN32
+#  define FILENO(__fp)          _fileno ((__fp))
+# elif defined __CYGWIN__  ||  defined __TURBOC__  ||  defined __unix__  ||  defined __EMX__  ||  defined _MSC_VER
+#  define FILENO(__fp)          fileno  ((__fp))
+# else
+#  define FILENO(__fp)          fileno  ((__fp))
+# endif
+#else
+#  define FILENO(__fd)          (__fd)
+#endif
+
+
+//
+// If we have access to a file via file name, we can open the file with an
+// additional "b" or a O_BINARY within the (f)open function to get a
+// transparent untranslated data stream which is necessary for audio bitstream
+// data and also for PCM data. If we are working with
+// stdin/stdout/FILENO_STDIN/FILENO_STDOUT we can't open the file with these
+// attributes, because the files are already open. So we need a non
+// standardized sequence to switch to this mode (not necessary for Unix).
+// Mostly the sequence is the same for incoming and outgoing streams, but only
+// mostly so we need one for IN and one for OUT.
+// Macros are called with the file pointer and you get back the untransalted file
+// pointer which can be equal or different from the original.
+//
+
+#if   defined __EMX__
+# define SETBINARY_IN(__fp)     (_fsetmode ( (__fp), "b" ), (__fp))
+# define SETBINARY_OUT(__fp)    (_fsetmode ( (__fp), "b" ), (__fp))
+#elif defined __TURBOC__ || defined __BORLANDC__
+# define SETBINARY_IN(__fp)     (setmode   ( FILENO ((__fp)),  O_BINARY ), (__fp))
+# define SETBINARY_OUT(__fp)    (setmode   ( FILENO ((__fp)),  O_BINARY ), (__fp))
+#elif defined __CYGWIN__
+# define SETBINARY_IN(__fp)     (setmode   ( FILENO ((__fp)), _O_BINARY ), (__fp))
+# define SETBINARY_OUT(__fp)    (setmode   ( FILENO ((__fp)), _O_BINARY ), (__fp))
+#elif defined _WIN32
+# define SETBINARY_IN(__fp)     (_setmode  ( FILENO ((__fp)), _O_BINARY ), (__fp))
+# define SETBINARY_OUT(__fp)    (_setmode  ( FILENO ((__fp)), _O_BINARY ), (__fp))
+#elif defined _MSC_VER
+# define SETBINARY_IN(__fp)     (setmode   ( FILENO ((__fp)),  O_BINARY ), (__fp))
+# define SETBINARY_OUT(__fp)    (setmode   ( FILENO ((__fp)),  O_BINARY ), (__fp))
+#elif defined __unix__
+# define SETBINARY_IN(__fp)     (__fp)
+# define SETBINARY_OUT(__fp)    (__fp)
+#elif 0
+# define SETBINARY_IN(__fp)     (freopen   ( NULL, "rb", (__fp) ), (__fp))
+# define SETBINARY_OUT(__fp)    (freopen   ( NULL, "wb", (__fp) ), (__fp))
+#else
+# define SETBINARY_IN(__fp)     (__fp)
+# define SETBINARY_OUT(__fp)    (__fp)
+#endif
+
+// file I/O using ANSI buffered file I/O via file pointer FILE* (fopen, fread, fwrite, fclose)
+#if  FILEIO == 1
+# define OFF_T                  signed long
+# define FILE_T                 FILE*
+# define OPEN(name)             fopen  (name, "rb" )
+# define OPENRW(name)           fopen  (name, "r+b")
+# define CREATE(name)           fopen  (name, "wb" )
+# define INVALID_FILEDESC       NULL
+# define CLOSE(fp)              fclose (fp)                  // CLOSE   returns -1 on error, otherwise 0
+# define READ(fp,ptr,len)       fread  (ptr, 1, len, fp)     // READ    returns -1 or 0 on error/EOF, otherwise > 0
+# define READ1(fp,ptr)          fread  (ptr, 1, 1, fp)       // READ    returns -1 or 0 on error/EOF, otherwise > 0
+# define WRITE(fp,ptr,len)      fwrite (ptr, 1, len, fp)     // WRITE   returns -1 or 0 on error/EOF, otherwise > 0
+# define SEEK(fp,offs,lbl)      fseek  (fp, offs, lbl)       // SEEK    returns -1 on error, otherwise >= 0
+# define FILEPOS(fp)            ftell  (fp)                  // FILEPOS returns -1 on error, otherwise >= 0
+# define STDIN                  stdin
+# define STDOUT                 stdout
+# define STDERR                 stderr
+# define FDOPEN(fd,mode)        fdopen (fd, mode)
+# define UNBUFFER(fp)           setvbuf(fp, NULL, _IONBF, 0 )
+# define FLUSH(fp)              fflush (fp)
+#endif /* FILEIO==1 */
+
+// file I/O using POSIX unbuffered file I/O via file descriptors (open, read, write, close)
+#if  FILEIO == 2
+# ifdef WIN32
+#  define OFF_T                 _off_t
+# else
+#  define OFF_T                 off_t
+# endif
+# define FILE_T                 int
+# define OPEN(name)             open  (name, O_RDONLY|O_BINARY)
+# define OPENRW(name)           open  (name, O_RDWR  |O_BINARY)
+# define CREATE(name)           open  (name, O_WRONLY|O_BINARY|O_TRUNC|O_CREAT, 0644)
+# define INVALID_FILEDESC       (-1)
+# define CLOSE(fd)              close (fd)                   // CLOSE   returns -1 on error, otherwise 0
+// # if defined HAVE_INCOMPLETE_READ
+// #  define READ(fd,ptr,len)      complete_read (fd, ptr, len) // READ    returns -1 or 0 on error/EOF, otherwise > 0
+// # else
+// #  define READ(fd,ptr,len)      (size_t)read   (fd, ptr, len)// READ    returns -1 or 0 on error/EOF, otherwise > 0
+// # endif
+# define READ1(fd,ptr)          (size_t)read   (fd, ptr, 1)  // READ    returns -1 or 0 on error/EOF, otherwise > 0
+# define WRITE(fd,ptr,len)      (size_t)write  (fd, ptr, len)// WRITE   returns -1 or 0 on error/EOF, otherwise > 0
+# define SEEK(fd,offs,lbl)      lseek  (fd, offs, lbl)       // SEEK    returns -1 on error, otherwise >= 0
+# define FILEPOS(fd)            lseek  (fd, 0L, SEEK_CUR)    // FILEPOS returns -1 on error, otherwise >= 0
+# define STDIN                  0
+# define STDOUT                 1
+# define STDERR                 2
+# define FDOPEN(fd,mode)        (fd)
+# define UNBUFFER(fd)           (void)(fd)
+# define FLUSH(fd)              (void)(fd)
+#endif /* FILEIO==2 */
+
+// file I/O using Turbo-C lowest level unbuffered file I/O via file descriptors (_open, _read, _write, _close)
+#if  FILEIO == 3
+# define OFF_T                  signed long
+# define FILE_T                 int
+# define OPEN(name)             _open (name, O_RDONLY)
+# define OPENRW(name)           _open (name, O_RDWR  )
+# define CREATE(name)           _creat(name, 0)
+# define INVALID_FILEDESC       (-1)
+# define CLOSE(fd)              _close (fd)                  // CLOSE   returns -1 on error, otherwise 0
+# define READ(fd,ptr,len)       (size_t)_read  (fd, ptr, len)// READ    returns -1 or 0 on error/EOF, otherwise > 0
+# define READ1(fd,ptr)          (size_t)_read  (fd, ptr, 1)  // READ    returns -1 or 0 on error/EOF, otherwise > 0
+# define WRITE(fd,ptr,len)      (size_t)_write (fd, ptr, len)// WRITE   returns -1 or 0 on error/EOF, otherwise > 0
+# define SEEK(fd,offs,lbl)      lseek  (fd, offs, lbl)       // SEEK    returns -1 on error, otherwise >= 0
+# define FILEPOS(fd)            lseek  (fd, 0L, SEEK_CUR)    // FILEPOS returns -1 on error, otherwise >= 0
+# define STDIN                  0
+# define STDOUT                 1
+# define STDERR                 2
+# undef  SETBINARY_IN
+# undef  SETBINARY_OUT
+# define SETBINARY_IN(fd)       (fd)
+# define SETBINARY_OUT(fd)      (fd)
+# define FDOPEN(fd,mode)        (fd)
+# define UNBUFFER(fd)           (void)(fd)
+# define FLUSH(fd)              (void)(fd)
+#endif /* FILEIO==3 */
+
+#if FILEIO != 2  &&  defined USE_HTTP
+# error HTTP can only be used by FILEIO==2
+#endif
+
+#if defined _WIN32  ||  defined __BEOS__
+# define WRITE_SOCKET(sock,ptr,len)     send (sock, ptr, len, 0)
+# define READ_SOCKET(sock,ptr,len)      recv (sock, ptr, len, 0)
+#else
+# define WRITE_SOCKET(sock,ptr,len)     write (sock, ptr, len)
+# define READ_SOCKET(sock,ptr,len)      read  (sock, ptr, len)
+#endif
+
+#ifdef _WIN32
+# define POPEN_READ_BINARY_OPEN(cmd)    _popen ((cmd), "rb")
+# define POPEN_WRITE_BINARY_OPEN(cmd)   _popen ((cmd), "wb")
+# define PCLOSE(fp)                     _pclose(fp)
+#else
+# define POPEN_READ_BINARY_OPEN(cmd)    popen ((cmd), "r")
+# define POPEN_WRITE_BINARY_OPEN(cmd)   popen ((cmd), "w")
+# define PCLOSE(fp)                     pclose(fp)
+#endif
+
+#ifndef S_ISDIR
+# if   defined S_IFDIR
+#  define S_ISDIR(x)            ((x) &   S_IFDIR)
+# elif defined _S_IFDIR
+#  define S_ISDIR(x)            ((x) &  _S_IFDIR)
+# elif defined __S_IFDIR
+#  define S_ISDIR(x)            ((x) & __S_IFDIR)
+# else
+#  error Cannot find a way to test for a directory
+# endif
+#endif /* !S_ISDIR */
+
+#if defined __unix__  ||  defined __bsdi__  ||  defined __FreeBSD__  ||  defined __OpenBSD__  ||  defined __NetBSD__  ||  defined __TURBOC__  ||  defined _WIN32  ||  defined __APPLE__
+# define ISATTY(fd)             isatty (fd)
+#else
+# define ISATTY(fd)             0
+#endif
+
+// Path separator
+#if defined __unix__  ||  defined __bsdi__  ||  defined __FreeBSD__  ||  defined __OpenBSD__  ||  defined __NetBSD__  ||  defined __APPLE__
+# define PATH_SEP               '/'
+# define DRIVE_SEP              '\0'
+# define EXE_EXT                ""
+# define DEV_NULL               "/dev/null"
+# define ENVPATH_SEP            ':'
+#elif defined _WIN32  ||  defined __TURBOC__  ||  defined __ZTC__  ||  defined _MSC_VER
+# define PATH_SEP               '\\'
+# define DRIVE_SEP              ':'
+# define EXE_EXT                ".exe"
+# define DEV_NULL               "\\nul"
+# define ENVPATH_SEP            ';'
+#else
+# define PATH_SEP               '/'         // Amiga: C:/
+# define DRIVE_SEP              ':'
+# define EXE_EXT                ""
+# define DEV_NULL               "nul"
+# define ENVPATH_SEP            ';'
+#endif
+
+// maximum length of file names
+#ifndef PATHLEN_MAX
+# if   defined FILENAME_MAX
+#  define PATHLEN_MAX           FILENAME_MAX
+# elif INT_MAX < 2147483647L
+#  define PATHLEN_MAX            128
+# else
+#  define PATHLEN_MAX           1024
+# endif
+#endif /* !PATHLEN_MAX */
+
+#ifdef _WIN32
+# define TitleBar(text)   SetConsoleTitle (text)
+#else
+# define TitleBar(text)   (void) (text)
+#endif
+
+
+//// constants /////////////////////////////////////////////////////
+#ifdef USE_SV8
+# define MAX_SV          "SV8"
+#else
+# define MAX_SV          "SV7"
+#endif
+
+#ifdef USE_ASM
+# define BUILD           "3DNOW!/SSE"
+#else
+# define BUILD           ""
+#endif
+
+
+#define COPYRIGHT        "(C) 1999-2003 Buschmann/Klemm/Piecha/Wolf"
+
+#define DECODER_DELAY    (512 - 32 + 1)
+#define BLK_SIZE         (36 * 32)
+
+
+//// logging defines, for development only /////////////////////////
+#if defined _WIN32  ||  defined __TURBOC__
+# define LOGPATH         ".\\"
+# define MUSICPATH       "D:\\AUDIO\\"
+#else
+# define LOGPATH         "./"
+# define MUSICPATH       "/Archive/Audio/"
+#endif
+#define _(x)             (void)(fprintf(stderr,"<%d>\n",(x)),fflush(stderr))
+
+#ifdef DEBUG
+# define REP(x)          (void)(x)
+#else
+# define REP(x)
+#endif
+
+
+//// numerical constants ///////////////////////////////////////////
+#define C00              (Float) 0.500000000000000000000000L    // Cxx = 0.5 / cos (xx*M_PI/64)
+#define C01              (Float) 0.500602998235196301334178L
+#define C02              (Float) 0.502419286188155705518560L
+#define C03              (Float) 0.505470959897543659956626L
+#define C04              (Float) 0.509795579104159168925062L
+#define C05              (Float) 0.515447309922624546962323L
+#define C06              (Float) 0.522498614939688880640101L
+#define C07              (Float) 0.531042591089784174473998L
+#define C08              (Float) 0.541196100146196984405269L
+#define C09              (Float) 0.553103896034444527838540L
+#define C10              (Float) 0.566944034816357703685831L
+#define C11              (Float) 0.582934968206133873665654L
+#define C12              (Float) 0.601344886935045280535340L
+#define C13              (Float) 0.622504123035664816182728L
+#define C14              (Float) 0.646821783359990129535794L
+#define C15              (Float) 0.674808341455005746033820L
+#define C16              (Float) 0.707106781186547524436104L
+#define C17              (Float) 0.744536271002298449773679L
+#define C18              (Float) 0.788154623451250224773056L
+#define C19              (Float) 0.839349645415527038721463L
+#define C20              (Float) 0.899976223136415704611808L
+#define C21              (Float) 0.972568237861960693780520L
+#define C22              (Float) 1.060677685990347471323668L
+#define C23              (Float) 1.169439933432884955134476L
+#define C24              (Float) 1.306562964876376527851784L
+#define C25              (Float) 1.484164616314166277319733L
+#define C26              (Float) 1.722447098238333927796261L
+#define C27              (Float) 2.057781009953411550808880L
+#define C28              (Float) 2.562915447741506178719328L
+#define C29              (Float) 3.407608418468718785698107L
+#define C30              (Float) 5.101148618689163857960189L
+#define C31              (Float)10.190008123548056810994678L
+
+#define SS05             (Float) 0.840896415253714543018917L      // 0.5^0.25
+
+
+#ifndef M_PI
+# define M_PI            3.1415926535897932384626433832795029     // 4*atan(1)
+# define M_PIl           3.1415926535897932384626433832795029L
+# define M_LN2           0.6931471805599453094172321214581766     // ln(2)
+# define M_LN2l          0.6931471805599453094172321214581766L
+# define M_LN10          2.3025850929940456840179914546843642     // ln 10 */
+# define M_LN10l         2.3025850929940456840179914546843642L
+#endif
+
+
+//// 'Cdecl' forces the use of standard C/C++ calling convention ///////
+#if   defined _WIN32
+# define Cdecl           __cdecl
+#elif defined __ZTC__
+# define Cdecl           _cdecl
+#elif defined __TURBOC__
+# define Cdecl           cdecl
+#else
+# define Cdecl
+#endif
+
+//// expect handling of GCC ////////////////////////////////////////
+#ifdef __GNUC__
+# if __GNUC__ < 3
+#  define __builtin_expect(cond,exp)  (cond)
+#  ifndef expect
+#    define expect(cond,exp)          __builtin_expect(cond,exp)
+#  endif
+# else
+#  ifndef expect
+#   define expect(cond,exp)           __builtin_expect(cond,exp)
+#  endif
+# endif
+#else
+# define __builtin_expect(cond,exp)   (cond)
+# ifndef expect
+#  define expect(cond,exp)            __builtin_expect(cond,exp)
+# endif
+#endif
+
+#define if0(x)                        if (expect(x,0))
+#define if1(x)                        if (expect(x,1))
+#define while0(x)                     while (expect(x,0))
+#define while1(x)                     while (expect(x,1))
+
+#ifndef __GNUC__
+# define __attribute__(x)
+#else
+# define __attribute__(x)
+#endif
+
+//// Remaining macros //////////////////////////////////////////////
+// selects input buffer size and some constants needed for input buffer handling
+#ifndef IBUFLOG2                 // must be at least 10 (bitrate always <626 kbps) or better 11 ( <1253 kbps)
+# if INT_MAX < 2147483647L
+#  define IBUFLOG2       11      // 8 KByte buffer, possible 11...13 (32 KByte limit)
+# else
+#  define IBUFLOG2       21      // 8 MByte buffer, possible 11...29 ( 2 GByte limit)
+# endif
+#endif
+#define IBUFSIZE         ((size_t)(1LU<<(IBUFLOG2)))
+#define IBUFSIZE2        ((size_t)((IBUFSIZE)/2))
+#define IBUFMASK         ((size_t)((IBUFSIZE)-1))
+
+// save memory space for 16 bit compiler (data + stack < 64 KByte)
+#if INT_MAX < 2147483647L
+# if VIRT_SHIFT     >  6
+#  undef  VIRT_SHIFT
+#  define VIRT_SHIFT   6
+# endif
+# if      IBUFLOG2  > 11
+#  undef  IBUFLOG2
+#  define IBUFLOG2    11
+# endif
+# define USE_HUFF_PACK
+# define USE_ARRAY_PACK
+#endif
+
+// generate a macro which contains information about compile time settings
+#define STR(x)   _STR(x)
+#define _STR(x)  #x
+#ifdef NDEBUG
+# define T1  ""
+#else
+# define T1  "DEBUG "
+#endif
+#if  defined USE_OSS_AUDIO  ||  defined USE_ESD_AUDIO  ||  defined USE_SUN_AUDIO  ||  defined USE_WIN_AUDIO
+# define T2  "SND "
+#else
+# define T2  ""
+#endif
+#ifdef USE_NICE
+# define T3  "NICE "
+#else
+# define T3  ""
+#endif
+#if defined USE_REALTIME
+# define T4  "RT "
+#else
+# define T4  ""
+#endif
+#ifdef HAVE_IEEE754_FLOAT
+# define T5  "IEEE "
+#else
+# define T5  ""
+#endif
+#define T6  "IO=" STR(FILEIO) " "
+#ifdef USE_HUFF_PACK
+# define T7  "H-PCK "
+#else
+# define T7  ""
+#endif
+#ifdef USE_ARRAY_PACK
+# define T8  "A-PCK "
+#else
+# define T8  ""
+#endif
+#define T9  "SHFT=" STR(VIRT_SHIFT) " "
+#define T10 "IBUF=" STR(IBUFLOG2) " "
+
+#define COMPILER_FLAGS  T1 T2 T3 T4 T5 T6 T7 T8 T9 T10
+
+// align a pointer by maybe incrementing it
+#define ALIGN(ptr,alignment) \
+                    (void*)((((ptrdiff_t)(ptr)) & (-(ptrdiff_t)(alignment))) + (alignment))   // aligns a pointer with alignment, the source array should be at least alignment-1 Bytes longer than the needed length
+
+
+//// Simple types //////////////////////////////////////////////////
+
+#if   CHAR_BIT == 8  &&  SCHAR_MAX == 127L
+typedef unsigned char       Uint8_t;    // guaranteed  8 bit unsigned integer type with range 0...255
+typedef signed   char       Int8_t;     // guaranteed  8 bit signed   integer type with range -128...127
+#else
+# error No  8 bit int type found. Tested: char
+#endif
+
+#if   SHRT_MAX == 32767L
+typedef unsigned short int  Uint16_t;   // guaranteed 16 bit unsigned integer type with range 0...65535
+typedef signed   short int  Int16_t;    // guaranteed 16 bit signed   integer type with range -32768...32767
+#else
+# error No 16 bit int type found. Tested: short
+#endif
+
+#if   INT_MAX == 2147483647L
+typedef unsigned int        Uint32_t;   // guaranteed 32 bit unsigned integer type with range 0...4294967295
+typedef signed   int        Int32_t;    // guaranteed 32 bit signed   integer type with range -2147483648...2147483647
+#elif LONG_MAX == 2147483647L
+typedef unsigned long int   Uint32_t;   // guaranteed 32 bit unsigned integer type with range 0...4294967295
+typedef signed   long int   Int32_t;    // guaranteed 32 bit signed   integer type with range -2147483648...2147483647
+#else
+# error No 32 bit int type found. Tested: int, long
+#endif
+
+#if    defined __C99__                 // C9x has a type which is exact 64 bit
+typedef int64_t             Int64_t;
+typedef uint64_t            Uint64_t;
+typedef intmax_t            IntMax_t;
+typedef uintmax_t           UintMax_t;
+# define IntMax_MIN        -9223372036854775808
+# define IntMax_MAX         9223372036854775807
+# define UintMax_MAX       18446744073709551615
+# define UintMAX_FP(x)      (long double)(x)
+#elif  defined __GNUC__                // GCC uses long long as 64 bit
+typedef signed   long long  Int64_t;
+typedef unsigned long long  Uint64_t;
+typedef signed   long long  IntMax_t;
+typedef unsigned long long  UintMax_t;
+# define IntMax_MIN        -9223372036854775808LL
+# define IntMax_MAX         9223372036854775807LL
+# define UintMax_MAX       18446744073709551615LLU
+# define UintMAX_FP(x)      (long double)(x)
+#elif defined _MSC_VER
+typedef signed   __int64    Int64_t;
+typedef unsigned __int64    Uint64_t;
+typedef signed   __int64    IntMax_t;
+typedef unsigned __int64    UintMax_t;
+# define IntMax_MIN        -9223372036854775808I64
+# define IntMax_MAX         9223372036854775807I64
+# define UintMax_MAX       18446744073709551615UI64
+# define UintMAX_FP(x)      (long double)(IntMax_t)(x)
+#elif defined LLONG_MAX               // long long (when existing) is normally 64 bit
+typedef signed   long long  Int64_t;
+typedef unsigned long long  Uint64_t;
+typedef signed   long long  IntMax_t;
+typedef unsigned long long  UintMax_t;
+# define IntMax_MIN        -9223372036854775808LL
+# define IntMax_MAX         9223372036854775807LL
+# define UintMax_MAX       18446744073709551615LLU
+# define UintMAX_FP(x)      (long double)(x)
+#elif  LONG_MAX > 0xFFFFFFFFLU         // long is longer than 33 bit, assume 64 bit
+typedef signed   long       Int64_t;
+typedef unsigned long       Uint64_t;
+typedef signed   long       IntMax_t;
+typedef unsigned long       UintMax_t;
+# define IntMax_MIN        -9223372036854775808L
+# define IntMax_MAX         9223372036854775807L
+# define UintMax_MAX       18446744073709551615LU
+# define UintMAX_FP(x)      (long double)(x)
+#elif  defined _WIN32                  // Microsoft and Intel call it __int64
+typedef signed   __int64    Int64_t;
+typedef unsigned __int64    Uint64_t;
+typedef signed   __int64    IntMax_t;
+typedef unsigned __int64    UintMax_t;
+# define IntMax_MIN        -9223372036854775808I64
+# define IntMax_MAX         9223372036854775807I64
+# define UintMax_MAX       18446744073709551615UI64
+# define UintMAX_FP(x)      (long double)(IntMax_t)(x)
+#else
+# define NO_INT64_T                    // no type mapped to 64 bit integer
+typedef signed   long       IntMax_t;
+typedef unsigned long       UintMax_t;
+# define IntMax_MIN        -2147483648L
+# define IntMax_MAX         2147483647L
+# define UintMax_MAX        4294967295LU
+# define UintMAX_FP(x)      (long double)(x)
+#endif
+
+
+#if defined _WIN32  &&  !defined __GNUC__  &&  !defined __C99__
+typedef signed long         ssize_t;
+#endif
+
+#ifdef USE_ARRAY_PACK
+typedef signed char         Bool_t;     // ==0: false, !=0: true
+#else
+typedef signed int          Bool_t;     // ==0: false, !=0: true
+#endif
+typedef Uint32_t            Ibuf_t;     // type for input buffer, currently this type must be 32 bit
+typedef signed   char       Schar;      // at least -127...+127
+typedef unsigned char       Uchar;      // at least 0...255
+typedef signed   short int  Short;      // at least -32767...+32767, memory economic type
+typedef unsigned short int  Ushort;     // at least 0...65535, memory economic type
+typedef signed   int        Int;        // at least -32767...+32767, fast type
+typedef unsigned int        Uint;       // at least 0...65535, fast type
+typedef signed   long int   Long;       // at least -2147483647...+2147483647, but more is better
+typedef unsigned long int   Ulong;      // at least 0...4294967295, but more is better
+//                          size_t;     // size of memory objects
+//                          ptrdiff_t;  // pointer differences, may be larger than size_t
+typedef float               Float32_t;  // guaranteed 32 bit floating point type
+typedef double              Float64_t;  // guaranteed 64 bit floating point type
+typedef float               Float;      // fastest floating point type, memory economic (used for all PCM calculations)
+#define SIZEOF_Float  4                 // size of the type 'Float' in sizeof units
+typedef double              Double;     // floating point with extended precision (more than 32 bit mantissa)
+typedef long double         Ldouble;    // most exact floating point format
+typedef Int16_t             Int2x16_t [2];
+typedef Int32_t             Int2x32_t [2];
+
+#if   defined MAKE_16BIT  ||  defined MAKE_24BIT  ||  defined MAKE_32BIT
+# ifdef NO_INT64_T
+#   error No 64 bit int type found, needed for HQ 16...32 bit output
+# endif
+typedef Int2x32_t           Int2xSample_t;
+# if defined MAKE_32BIT
+#  define SAMPLE_SIZE        32
+#  define PROG_NAME          "mppdec32"
+#  define SAMPLE_SIZE_STRING " (32 bit HQ)"
+#  define Write_PCM(fd,p,b)  Write_PCM_HQ_2x32bit ( fd, p, b )
+#  define Synthese_Filter(Stream,offset,Vi,Yi,ch) \
+                            Synthese_Filter_32_C ( Stream, offset, Vi, Yi, ch )
+#  undef  USE_ESD_AUDIO
+# elif defined MAKE_24BIT
+#  define SAMPLE_SIZE        24
+#  define PROG_NAME          "mppdec24"
+#  define SAMPLE_SIZE_STRING " (24 bit HQ)"
+#  define Write_PCM(fd,p,b)  Write_PCM_HQ_2x24bit ( fd, p, b )
+#  define Synthese_Filter(Stream,offset,Vi,Yi,ch) \
+                            Synthese_Filter_32_C ( Stream, offset, Vi, Yi, ch )
+#  undef  USE_ESD_AUDIO
+# elif defined MAKE_16BIT
+#  define SAMPLE_SIZE        16
+#  define PROG_NAME          "mppdec16"
+#  define SAMPLE_SIZE_STRING " (16 bit HQ)"
+#  define Write_PCM(fd,p,b)  Write_PCM_HQ_2x16bit ( fd, p, b )
+#  define Synthese_Filter(Stream,offset,Vi,Yi,ch) \
+                            Synthese_Filter_32_C ( Stream, offset, Vi, Yi, ch )
+# endif
+#else
+typedef Int2x16_t           Int2xSample_t;
+# define SAMPLE_SIZE        16
+# define PROG_NAME          "mppdec"
+# define SAMPLE_SIZE_STRING ""
+# define Write_PCM(fd,p,b)  Write_PCM_2x16bit ( fd, p, b )
+# ifdef USE_ASM
+#  define Synthese_Filter(Stream,offset,Vi,Yi,ch) \
+                            Synthese_Filter_16 ( Stream, offset, Vi, Yi )
+# else
+#  define Synthese_Filter(Stream,offset,Vi,Yi,ch) \
+                            Synthese_Filter_16_C ( Stream, offset, Vi, Yi )
+# endif /* USE_ASM */
+#endif
+
+
+//// More complex types ////////////////////////////////////////////
+typedef struct {
+    Int    L [36];
+    Int    R [36];
+} Quant_t ;
+
+typedef struct {
+    Uint   L;
+    Uint   R;
+} UPair_t ;
+
+typedef struct {
+    Int    L;
+    Int    R;
+} Pair_t ;
+
+typedef struct {
+#ifdef USE_ARRAY_PACK
+    Schar  L;
+    Schar  R;
+#else
+    Int    L;
+    Int    R;
+#endif
+} CPair_t ;
+
+typedef Float     FloatArray [32];
+typedef UPair_t   UPairArray [32];
+typedef Pair_t    PairArray  [32];
+typedef CPair_t   CPairArray [32];
+typedef Float     SCFTriple   [3];
+
+typedef struct {
+    OFF_T         FileSize;
+    Int           GenreNo;
+    Int           TrackNo;
+    char          Genre   [128];
+    char          Year    [ 20];
+    char          Track   [  8];
+    char          Title   [256];
+    char          Artist  [256];
+    char          Album   [256];
+    char          Comment [512];
+} TagInfo_t ;
+
+typedef void  (*SyntheseFilter16_t) ( Int2x16_t* Stream, Int* const offset, Float* Vi, const FloatArray* Yi );
+typedef void  (*SyntheseFilter32_t) ( Int2x32_t* Stream, Int* const offset, Float* Vi, const FloatArray* Yi, int ch );
+typedef Int   (*HeaderWriter_t)     ( FILE_T outputFile, Ldouble  SampleFreq, Uint BitsPerSample, Uint Channels, Ulong SamplesPerChannel );
+
+#if defined MAKE_16BIT  ||  defined MAKE_24BIT  ||  defined MAKE_32BIT
+typedef struct {
+    const Float*  FilterCoeff;
+    Uint64_t      Mask;
+    Float64_t     Add;
+    Float         Dither;
+    Uint32_t      Overdrives;
+    Int64_t       MaxLevel;
+    Bool_t        NoShaping;
+    Float         ErrorHistory     [2] [16];       // max. 2 channels, 16th order Noise shaping
+    Float         DitherHistory    [2] [16];
+    Int32_t       LastRandomNumber [2];
+} dither_t;
+#else
+typedef struct {
+    Uint32_t      Overdrives;
+    Int32_t       MaxLevel;
+} dither_t;
+#endif
+
+
+//// Variables /////////////////////////////////////////////////////
+
+// decode.c
+extern Ibuf_t             InputBuff [IBUFSIZE]; // read buffer for the MP+ data stream
+extern size_t             InputCnt;             // current offset in this buffer
+
+// // huffsv7.c
+// extern Huffman_t          HuffHdr    [10];
+// extern Huffman_t          HuffSCFI   [ 4];
+// extern Huffman_t          HuffDSCF   [16];
+// extern Huffman_t          HuffQ1 [2] [ 3*3*3];
+// extern Huffman_t          HuffQ2 [2] [ 5*5];
+// extern Huffman_t          HuffQ3 [2] [ 7];
+// extern Huffman_t          HuffN3 [2] [ 7*7];
+// extern Huffman_t          HuffQ4 [2] [ 9];
+// extern Huffman_t          HuffQ5 [2] [15];
+// extern Huffman_t          HuffQ6 [2] [31];
+// extern Huffman_t          HuffQ7 [2] [63];
+// extern Huffman_t          HuffN8 [2][127];
+// extern const Huffman_t*   HuffQ  [2] [ 8];
+// extern const Huffman_t*   HuffN  [2] [ 9];
+// extern Uint8_t            LUT1_0  [1<< 6];
+// extern Uint8_t            LUT1_1  [1<< 9];
+// extern Uint8_t            LUT2_0  [1<< 7];
+// extern Uint8_t            LUT2_1  [1<<10];
+// extern Uint8_t            LUT3_0  [1<< 4];
+// extern Uint8_t            LUT3_1  [1<< 5];
+// extern Uint8_t            LUT4_0  [1<< 4];
+// extern Uint8_t            LUT4_1  [1<< 5];
+// extern Uint8_t            LUT5_0  [1<< 6];
+// extern Uint8_t            LUT5_1  [1<< 8];
+// extern Uint8_t            LUT6_0  [1<< 7];
+// extern Uint8_t            LUT6_1  [1<< 7];
+// extern Uint8_t            LUT7_0  [1<< 8];
+// extern Uint8_t            LUT7_1  [1<< 8];
+// extern Uint8_t            LUTDSCF [1<< 6];
+
+// mppdec.c
+extern Float              Y_L      [36] [32];
+extern Float              Y_R      [36] [32];
+extern CPair_t            SCF_Index [3] [32];      // Scalefactor
+extern CPair_t            Res           [32];      // resolution steps of the subbands
+extern Quant_t            Q             [32];      // quantized samples
+extern CPair_t            SCFI          [32];      // transfer order of the SCF
+extern Bool_t             MS_Band       [32];      // subband-wise flag for M/S-signal guidance
+extern Bool_t             MS_used;                 // global flag for M/S-signal guidance
+extern Bool_t             IS_used;
+
+#define LITTLE                  0
+#define BIG                     1
+extern Bool_t                   output_endianess;
+#if   ENDIAN == HAVE_LITTLE_ENDIAN
+# define machine_endianess      LITTLE
+#elif ENDIAN == HAVE_BIG_ENDIAN
+# define machine_endianess      BIG
+#endif
+
+// requant.c
+extern Float              __SCF    [6 + 128];       // tabulated Scalefactors from -6 to +127
+#define SCF             ( __SCF + 6 )
+extern Int8_t             Q_bit         [32];       // number of bits to save the resolution (SV6)
+extern Int8_t             Q_res         [32] [16];  // Index -> resolution (SV6)
+extern Uint               Bitrate;
+extern Int                Min_Band;
+extern Float              __Cc          [1 + 18];
+extern const Uint         __Dc          [1 + 18];
+#define Cc              ( __Cc + 1 )
+#define Dc              ( __Dc + 1 )
+
+// synthtab.c
+extern const Float        Cos64         [32];
+extern const Float        Di_opt        [32] [16];
+
+// stderr.c
+
+
+//// procedures/functions //////////////////////////////////////////
+// cpu_feat.c
+Bool_t Cdecl  Has_MMX                 ( void );
+Bool_t Cdecl  Has_SIMD                ( void );
+Bool_t Cdecl  Has_SIMD2               ( void );
+Bool_t Cdecl  Has_3DNow               ( void );
+
+// decode.c
+void       Bitstream_init             ( void );
+Ulong      BitsRead                   ( void );
+Uint32_t   Bitstream_read             ( Int  bits );
+Uint32_t   Bitstream_peek             ( Uint pos, Int bits );
+void       Bitstream_skip             ( Uint bits );
+Uint32_t   Bitstream_preview          ( Int  bits );  // same as above, but data doesn't get receipted yet
+void       Read_Bitstream_SV6         ( void );
+void       Read_Bitstream_SV7         ( void );
+void       Read_Bitstream_SV8         ( void );
+
+// http.c
+int        http_open                  ( const char* URL );
+
+// huffsv7.c
+void       Init_Huffman_Decoder_SV7   ( void );
+
+// huffsv46.c
+void       Init_Huffman_Decoder_SV4_6 ( void );
+
+// id3tag.c
+Int        Read_ID3V1_Tags            ( FILE_T fp, TagInfo_t* tip );
+Int        Read_APE_Tags              ( FILE_T fp, TagInfo_t* tip );
+
+// requant.c
+void       Init_QuantTab              ( Int maximum_Band, Bool_t used_IS, Double amplification, Uint StreamVersion );
+
+// synth.c
+Uint32_t   random_int                 ( void );
+
+void Cdecl Calculate_New_V_i387       ( const Float* Sample, Float* V );
+void Cdecl Calculate_New_V_3DNow      ( const Float* Sample, Float* V );
+void Cdecl New_V_Helper2              ( Float* A, const Float* Sample );
+void Cdecl New_V_Helper3              ( Float* A, const Float* Sample );
+void Cdecl New_V_Helper4              ( Float* V );
+
+void Cdecl VectorMult_i387            ( void* buff, const Float* V );
+void Cdecl VectorMult_3DNow           ( void* buff, const Float* V );
+void Cdecl VectorMult_SIMD            ( void* buff, const Float* V );
+
+void       Synthese_Filter_16_C       ( Int2x16_t* Stream, Int* const offset, Float* Vi, const FloatArray* Yi );
+void       Synthese_Filter_32_C       ( Int2x32_t* Stream, Int* const offset, Float* Vi, const FloatArray* Yi, Uint channel );
+
+void Cdecl Reset_FPU                  ( void );
+void Cdecl Reset_FPU_3DNow            ( void );
+void Cdecl memcpy_dn_MMX              ( void* dst, const void* src, size_t words64byte  );
+void Cdecl memcpy_dn_SIMD             ( void* dst, const void* src, size_t words128byte );
+
+void       Init_Dither                ( Int bits, int shapingtype, Double dither );
+// void       OverdriveReport            ( void );
+SyntheseFilter16_t
+           Get_Synthese_Filter        ( void );
+
+// wave_out.c
+Int        Write_WAVE_Header          ( FILE_T outputFile, Ldouble SampleFreq, Uint BitsPerSample, Uint Channels, Ulong SamplesPerChannel );
+Int        Write_AIFF_Header          ( FILE_T outputFile, Ldouble SampleFreq, Uint BitsPerSample, Uint Channels, Ulong SamplesPerChannel );
+Int        Write_Raw_Header           ( FILE_T outputFile, Ldouble SampleFreq, Uint BitsPerSample, Uint Channels, Ulong SamplesPerChannel );
+Int        Set_DSP_OSS_Params         ( FILE_T outputFile, Ldouble SampleFreq, Uint BitsPerSample, Uint Channels );
+Int        Set_DSP_Sun_Params         ( FILE_T outputFile, Ldouble SampleFreq, Uint BitsPerSample, Uint Channels );
+Int        Set_ESD_Params             ( FILE_T dummyFile , Ldouble SampleFreq, Uint BitsPerSample, Uint Channels );
+Int        Set_WIN_Params             ( FILE_T dummyFile , Ldouble SampleFreq, Uint BitsPerSample, Uint Channels );
+Int        Set_IRIX_Params            ( FILE_T dummyFile , Ldouble SampleFreq, Uint BitsPerSample, Uint Channels );
+size_t     Write_PCM_2x16bit          ( FILE_T outputFile, Int2x16_t* data, size_t len );
+size_t     Write_PCM_HQ_2x16bit       ( FILE_T outputFile, Int2x32_t* data, size_t len );
+size_t     Write_PCM_HQ_2x24bit       ( FILE_T outputFile, Int2x32_t* data, size_t len );
+size_t     Write_PCM_HQ_2x32bit       ( FILE_T outputFile, Int2x32_t* data, size_t len );
+int        WIN_Play_Samples           ( const void* buff, size_t len );
+int        IRIX_Play_Samples          ( const void* buff, size_t len );
+int        WIN_Audio_close            ( void );
+int        IRIX_Audio_close           ( void );
+void       DisableSUID                ( void );
+void       EnableSUID                 ( void );
+
+// pipeopen.c
+FILE*      pipeopen                   ( const char* command, const char* filename );
+
+// stderr.c
+void       SetStderrSilent            ( Bool_t state );
+Bool_t     GetStderrSilent            ( void );
+int Cdecl  stderr_printf              ( const char* format, ... );
+
+// _setargv.c
+long       treewalk                   ( const char* start, const char** mask, int (*fn)(const char* filename, void* aux), void* aux );
+void       mysetargv                  ( int* argc, char*** argv, const char** extentions );
+
+#if ENDIAN == HAVE_BIG_ENDIAN
+
+# define ReadLE32(dst,psrc)       dst = *(Uint32_t*)(psrc)
+# define ReadBE32(dst,psrc)                           \
+       ((Uint8_t*)&(dst))[0] = ((Uint8_t*)(psrc))[3], \
+       ((Uint8_t*)&(dst))[1] = ((Uint8_t*)(psrc))[2], \
+       ((Uint8_t*)&(dst))[2] = ((Uint8_t*)(psrc))[1], \
+       ((Uint8_t*)&(dst))[3] = ((Uint8_t*)(psrc))[0]
+
+
+#elif defined __i386__           /* 486+ */
+
+#  define ReadBE32(dst,psrc)      __asm__ ( "bswap %0" : "=r" (dst) : "0" (*(Uint32_t*)(psrc)) )
+#  define ReadLE32(dst,psrc)       dst = *(Uint32_t*)(psrc)
+
+# else
+
+#  define ReadBE32(dst,psrc)                          \
+       ((Uint8_t*)&(dst))[0] = ((Uint8_t*)(psrc))[3], \
+       ((Uint8_t*)&(dst))[1] = ((Uint8_t*)(psrc))[2], \
+       ((Uint8_t*)&(dst))[2] = ((Uint8_t*)(psrc))[1], \
+       ((Uint8_t*)&(dst))[3] = ((Uint8_t*)(psrc))[0]
+#  define ReadLE32(dst,psrc)       dst = *(Uint32_t*)(psrc)
+
+# endif
+
+#ifdef _MSC_VER
+#pragma warning ( disable : 4244 )
+#endif
+
+#endif /* MPPDEC_MPPDEC_H */
+
+/* end of mppdec.h */
Index: /libmpc/branches/r2d/mppenc/mppenc.c
===================================================================
--- /libmpc/branches/r2d/mppenc/mppenc.c	(revision 133)
+++ /libmpc/branches/r2d/mppenc/mppenc.c	(revision 133)
@@ -0,0 +1,1820 @@
+/*
+ * Musepack audio compression
+ * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf
+ *
+ * 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
+ */
+
+/* overflow of subband-samples */
+
+#include <memory.h>
+#include <time.h>
+#include <errno.h>
+
+#include "mppenc.h"
+#include "mpcmath.h"
+
+/* G L O B A L  V A R I A B L E S */
+float         Power_L    [32] [3];
+float         Power_R    [32] [3];
+
+/* MS-Coding */
+int           PredictionBands =  0;
+int           DisplayUpdateTime = 1;
+int           APE_Version     = 2000;
+int           LowDelay        = 0;
+Bool_t        EnableTags      = FALSE;
+Bool_t        IsEndBeep       = FALSE;
+
+#define MODE_OVERWRITE          0
+#define MODE_NEVER_OVERWRITE    1
+#define MODE_ASK_FOR_OVERWRITE  2
+
+/* other general global variables */
+unsigned int  DelInput        = 0;      // deleting the input file after encoding
+unsigned int  WriteMode       = MODE_ASK_FOR_OVERWRITE;      // overwriting a possibly existing MPC file
+unsigned int  verbose         = 0;      // more information during output
+unsigned int  NoUnicode       = 1;      // console is unicode or not (tag translation)
+UintMax_t     SamplesInWAVE   = 0;      // number of samples per channel in the WAV file
+float         MaxOverFlow     = 0.f;    // maximum overflow
+float         ScalingFactorl  = 1.f;    // Scaling the input signal
+float         ScalingFactorr  = 1.f;    // Scaling the input signal
+float         FadeShape       = 1.f;    // Shape of the fade
+float         FadeInTime      = 0.f;    // Duration of FadeIn in secs
+float         FadeOutTime     = 0.f;    // Duration of FadeOut in secs
+float         SkipTime        = 0.f;    // Skip the beginning of the file (sec)
+double        Duration        = 1.e+99; // Maximum encoded audio length
+Bool_t        FrontendPresent = 0;      // Flag for frontend-detection
+Bool_t        XLevel          = 1;      // Encode extreme levels with relative SCFs
+
+#if MPPENC_MINOR % 2 == 0
+#define _cat(a,b,c,d) #a"."#b"."#c"."#d" --stable--"
+#else
+#define _cat(a,b,c,d) #a"."#b"."#c"."#d" --unstable--"
+#endif
+
+#define cat(a,b,c,d) _cat(a,b,c,d)
+#define MPPENC_VERSION cat(MPPENC_MAJOR,MPPENC_MINOR,MPPENC_IMPLEMENT,MPPENC_BUILD)
+
+const char    About []        = "MPC Encoder " MPPENC_VERSION " (C) 1999-2005 Buschmann/Klemm/Piecha/MDT";
+
+
+#if defined _WIN32  ||  defined __TURBOC__
+# include <conio.h>
+#else
+
+# ifdef USE_TERMIOS
+#  include <termios.h>
+
+static struct termios  stored_settings;
+
+static void
+echo_on ( void )
+{
+    tcsetattr ( 0, TCSANOW, &stored_settings );
+}
+
+static void
+echo_off ( void )
+{
+    struct termios  new_settings;
+
+    tcgetattr ( 0, &stored_settings );
+    new_settings = stored_settings;
+
+    new_settings.c_lflag     &= ~ECHO;
+    new_settings.c_lflag     &= ~ICANON;        /* Disable canonical mode, and set buffer size to 1 byte */
+    new_settings.c_cc[VTIME]  = 0;
+    new_settings.c_cc[VMIN]   = 1;
+
+    tcsetattr ( 0, TCSANOW, &new_settings );
+}
+
+# else
+#  define echo_off()  (void)0
+#  define echo_on()   (void)0
+# endif
+
+static int
+getch ( void )
+{
+    unsigned char  buff [1];
+    int            ret;
+
+    echo_off ();
+    ret = READ1 ( STDIN, buff );
+    echo_on ();
+    return ret == 1  ?  buff[0]  :  -1;
+}
+
+#endif
+
+
+static int
+waitkey ( void )
+{
+    int  c;
+
+    fflush (stdout);
+    while ( (c = getch() ) <= ' ' )
+        ;
+    return c;
+}
+
+
+
+
+static void
+longhelp ( PsyModel * m )
+{
+    stderr_printf (
+             "\n"
+             "\033[1m\rUsage:\033[0m\n"
+             "  mppenc [--options] <Input_File>\n"
+             "  mppenc [--options] <Input_File> <Output_File>\n"
+             "  mppenc [--options] <List_of_Input_Files> <Output_File>        (not yet supp.)\n"
+             "  mppenc [--options] <List_of_Input_Files> <Output_Directory>   (not yet supp.)\n"
+             "\n" );
+
+    stderr_printf (
+             "\033[1m\rInput_File must be of the following:\033[0m\n"
+             "  -                stdin                 (only RIFF WAVE files)\n"
+             "  /dev/audio       soundcard             (using OSS, 44.1 kHz)\n"
+             "  *.wav            RIFF WAVE file\n"
+             "  *.raw/cdr        Raw PCM               (2ch, 16bit, 44.1kHz)\n"
+             "  *.pac/lpac       LPAC file             (Windows Only)\n"
+             "  *.fla/flac       FLAC file\n"
+             "  *.ape            Monkey's Audio file   (APE extension only)\n"
+             "  *.rka/rkau       RK Audio file         (Windows Only)\n"
+             "  *.sz             SZIP file\n"
+             "  *.shn            Shorten file\n"
+             "  *.wv             Wavpack File\n"
+             "  *.ofr            OptimFROG file        (Windows Only)\n"
+             "\n"
+             "  Currently only 32, 37.8, 44.1 and 48 kHz, 1-8 channels, 8-32 bit linear PCM\n"
+             "  is supported. When using one of the lossless compressed formats, a proper\n"
+             "  binary must be installed within the system's $PATH.\n"
+             "\n"
+             "\033[1m\rOutput_File must be of the following: (or generated from Input_File)\033[0m\n"
+             "  *.mpc            Musepack file\n"
+             "  *.mp+/mpp        MPEGplus file         (Deprecated)\n"
+             "  -                stdout\n"
+             "  /dev/null        trash can\n"
+             "\n" );
+
+    stderr_printf (
+             "\033[1m\rProfiles and Quality Scale:\033[0m\n"
+             "\n"
+             "  Option of using a profile (--radio) or mapped quality scale (--quality 4.0).\n"
+             "  In addition, quality scale is effective centesimally. (i.e. --quality 4.25)\n"
+             "  Available options are as follows:\n"
+             "\n"
+             "  below telephone  (--quality 0.00)   poor quality          (~  20 kbps)\n"
+             "  below telephone  (--quality 1.00)   poor quality          (~  30 kbps)\n"
+             "  --telephone      (--quality 2.00)   low quality           (~  60 kbps)\n"
+             "  --thumb          (--quality 3.00)   low/medium quality    (~  90 kbps)\n"
+             "  --radio          (--quality 4.00)   medium quality        (~ 130 kbps)\n"
+             "  --standard       (--quality 5.00)   high quality, (dflt)  (~ 180 kbps)\n"
+             "   (or --normal)\n"
+             "  --extreme        (--quality 6.00)   excellent quality     (~ 210 kbps)\n"
+             "   (or --xtreme)\n"
+             "  --insane         (--quality 7.00)   excellent quality     (~ 240 kbps)\n"
+             "  --braindead      (--quality 8.00)   excellent quality     (~ 270 kbps)\n"
+             "  above braindead  (--quality 9.00)   excellent quality     (~ 300 kbps)\n"
+             "  above braindead  (--quality 10.00)  excellent quality     (~ 350 kbps)\n"
+             "\n" );
+
+    stderr_printf (
+             "\033[1m\rFile/Message handling:\033[0m\n"
+             "  --silent         repress console messages                 (dflt: off)\n"
+             "  --verbose        increase verbosity                       (dflt: off)\n"
+             "  --longhelp       print this help text\n"
+             "  --stderr foo     append messages to file 'foo'\n"
+             "  --neveroverwrite never overwrite existing Output_File     (dflt: off)\n"
+             "  --interactive    ask to overwrite an existing Output_File (dflt: on)\n"
+             "  --overwrite      overwrite existing Output_File           (dflt: off)\n"
+             "  --deleteinput    delete Input_File after encoding         (dflt: off)\n"
+             "  --beep           beep when encoding is finished           (dflt: off)\n"
+             "\n" );
+
+    stderr_printf (
+             "\033[1m\rTagging (uses APE 2.0 tags):\033[0m\n"
+             "  --tag key=value  Add tag \"key\" with \"value\" as contents\n"
+             "  --tagfile key=f  dto., take value from a file 'f'\n"
+             "  --tagfile key    dto., take value from console\n"
+             "  --artist 'value' shortcut for --tag 'Artist=value'\n"
+             "  --album 'value'  shortcut for --tag 'Album=value'\n"
+             "                   other possible keys are: debutalbum, publisher, conductor,\n"
+             "                   title, subtitle, track, comment, composer, copyright,\n"
+             "                   publicationright, filename, recordlocation, recorddate,\n"
+             "                   ean/upc, year, releasedate, genre, media, index, isrc,\n"
+             "                   abstract, bibliography, introplay, media, language, ...\n"
+             "  --unicode        unicode input from console\n"
+             "  --writetags      enable tags                              (dflt: off)\n"
+             "\n" );
+
+    stderr_printf (
+             "\033[1m\rAudio processing:\033[0m\n" );
+    stderr_printf (
+             "  --skip x         skip the first x seconds  (dflt: %3.1f)\n",   SkipTime );
+    stderr_printf (
+             "  --dur x          stop encoding after at most x seconds of encoded audio\n" );
+    stderr_printf (
+             "  --fade x         fadein+out in seconds\n" );
+    stderr_printf (
+             "  --fadein x       fadein  in seconds (dflt: %3.1f)\n",                   FadeInTime );
+    stderr_printf (
+             "  --fadeout x      fadeout in seconds (dflt: %3.1f)\n",                   FadeOutTime );
+    stderr_printf (
+             "  --fadeshape x    fade shape (dflt: %3.1f),\n"
+             "                   see http://www.uni-jena.de/~pfk/mpc/img/fade.png\n",   FadeShape );
+    stderr_printf (
+             "  --scale x        scale input signal by x (dflt: %7.5f)\n",              ScalingFactorl );
+    stderr_printf (
+             "  --scale x,y      scale input signal, separate for each channel\n" );
+
+    stderr_printf (
+             "\033[1m\rExpert settings:\033[0m\n" );
+    stderr_printf (
+             "==Masking thresholds======\n" );
+    stderr_printf (
+             "  --quality x      set Quality to x (dflt: 5)\n" );
+    stderr_printf (
+             "  --nmt x          set NMT value to x dB (dflt: %4.1f)\n", m->NMT );
+    stderr_printf (
+             "  --tmn x          set TMN value to x dB (dflt: %4.1f)\n", m->TMN );
+    stderr_printf (
+             "  --pns x          set PNS value to x dB (dflt: %4.1f)\n", m->PNS );
+    stderr_printf (
+             "==ATH/Bandwidth settings==\n" );
+    stderr_printf (
+             "  --bw x           maximum bandwidth in Hz (dflt: %4.1f kHz)\n", (m->Max_Band+1)*(m->SampleFreq/32000.) );
+    stderr_printf (
+             "  --minSMR x       minimum SMR of x dB over encoded bandwidth (dflt: %2.1f)\n",  m->minSMR );
+    stderr_printf (
+             "  --ltq xyy        x=0: ISO threshold in quiet (not recommended)\n"
+             "                   x=1: more sensitive threshold in quiet (Buschmann)\n"
+             "                   x=2: even more sensitive threshold in quiet (Filburt)\n"
+             "                   x=3: Klemm\n"
+             "                   x=4: Buschmann-Klemm Mix\n"
+             "                   x=5: minimum of Klemm and Buschmann (dflt)\n"
+             "                   y=00...99: HF roll-off (00:+30 dB, 99:-30 dB @20 kHz\n" );
+    stderr_printf (
+             "  --ltq_gain x     add offset of x dB to chosen ltq (dflt: %+4.1f)\n",       m->Ltq_offset   );
+    stderr_printf (
+             "  --ltq_max x      maximum level for ltq (dflt: %4.1f dB)\n",                m->Ltq_max      );
+    stderr_printf (
+			"  --ltq_var x      adaptive threshold in quiet: 0: off, >0: on (dflt: %g)\n", m->varLtq    );
+    stderr_printf (
+			"  --tmpMask x      exploit postmasking: 0: off, 1: on (dflt: %i)\n",         m->tmpMask_used );
+    stderr_printf (
+             "==Stuff settings==========\n" );
+    stderr_printf (
+             "  --ms x           Mid/Side Stereo, 0: off, 1: reduced, 2: on, 3: decoupled,\n"
+             "                   10: enhanced 1.5/3 dB, 11: 2/6 dB, 12: 2.5/9 dB,\n"
+             "                   13: 3/12 dB, 15: 3/oo dB (dflt: %i)\n",                        m->MS_Channelmode );
+    stderr_printf (
+			"  --ans x          Adaptive Noise Shaping Order: 0: off, 1...6: on (dflt: %i)\n", m->NS_Order );
+    stderr_printf (
+			"  --cvd x          ClearVoiceDetection, 0: off, 1: on, 2: dual (dflt: %i)\n",     m->CVD_used );
+    stderr_printf (
+			"  --shortthr x     short FFT threshold (dflt: %4.1f)\n",                          m->ShortThr );
+    stderr_printf (
+             "  --transdet x     slewrate for transient detection (dflt: %3.1f)\n",             m->TransDetect );
+    stderr_printf (
+             "  --minval x       calculation of MinVal (1:Buschmann, 2,3:Klemm)\n" );
+    stderr_printf (
+             "  --noxlevel       use old filterbank clipping solving strategy\n" );
+    stderr_printf (
+             "\n" );
+
+    stderr_printf (
+             "\033[1m\rExamples:\033[0m\n"
+             "  mppenc inputfile.wav\n"
+             "  mppenc inputfile.wav outputfile.mpc\n"
+             "  mppenc --radio inputfile.wav outputfile.mpc\n"
+             "  mppenc --silent --radio --pns 0.25 inputfile.wav outputfile.mpc\n"
+             "  mppenc --nmt 12 --tmn 28 inputfile.wav outputfile.mpc\n"
+             "\n"
+             "For further information see the file 'MANUAL.TXT'.\n" );
+}
+
+
+static void
+shorthelp ( void )
+{
+    stderr_printf (
+             "\n"
+             "\033[1m\rUsage:\033[0m\n"
+             "  mppenc [--options] <Input_File>\n"
+             "  mppenc [--options] <Input_File> <Output_File>\n"
+             "\n"
+
+             "\033[1m\rStandard options:\033[0m\n"
+             "  --silent         repress console messages                 (dflt: off)\n"
+             "  --verbose        increase verbosity                       (dflt: off)\n"
+             "  --deleteinput    delete Input_File after encoding         (dflt: off)\n"
+             "  --overwrite      overwrite existing Output_File           (dflt: off)\n"
+             "  --fade sec       fade in and out with 'sec' duration      (dflt: 0.0)\n"
+             "\n"
+
+             "\033[1m\rProfiles and Quality Scale:\033[0m\n"
+             "  --thumb          (--quality 3.00)   low/medium quality    (~  90 kbps)\n"
+             "  --radio          (--quality 4.00)   medium quality        (~ 130 kbps)\n"
+             "  --standard       (--quality 5.00)   high quality, (dflt)  (~ 180 kbps)\n"
+             "  --extreme        (--quality 6.00)   excellent quality     (~ 210 kbps)\n"
+             "\n"
+
+             "\033[1m\rExamples:\033[0m\n"
+             "  mppenc inputfile.wav\n"
+             "  mppenc inputfile.wav outputfile.mpc\n"
+             "  mppenc --extreme inputfile.wav outputfile.mpc\n"
+             "  mppenc --silent --radio inputfile.wav outputfile.mpc\n"
+             "\n"
+             "For further information see the file 'MANUAL.TXT' or use option --longhelp.\n" );
+}
+
+
+/*
+ *  Wishes for fading:
+ *
+ *            _____________________
+ *           /|                   |\
+ *         /  |                   |  \
+ *        /   |                   |   \
+ *  ____/     |                   |     \______________
+ *  |  |      |                   |      |  |
+ *  |t1|  t2  |                   |  t4  |t5|
+ *  |                 t3                    |
+ *     |<-------------- M P C ------------->|
+ *  |<-------------------- W A V E ------------------>|
+ *
+ *   t1: StartTime   (Standard: 0, positive: from beginning of file, negative: from end of file)
+ *   t2: FadeInTime  (Standard: 0, positive: Fadetime)
+ *   t3: EndTime     (Standard: 0, non-positive: from end of file, positive: from beginning of file)
+ *   t4: FadeOutTime (Standard: 0, positive: Fadetime)
+ *   t5: PostGapTime (Standard: 0, positive: additional silence)
+ *
+ * The beginning of phase t4 can also be triggered by the signal SIGINT.
+ * With SIGTERM, the current frame is fully decoded and then terminated.
+ *
+ * Another question is if you can't put t1 before the zero, same with t3 and t5
+ * (track-spanning cutting).
+ */
+
+float  bump_exp   = 1.f;
+float  bump_start = 0.040790618517f;
+
+
+static void
+setbump ( double e )
+{
+    bump_exp   = e;
+    bump_start = 1 - sqrt (1 - 1 / (1 - log(1.e-5) / e));
+}
+
+
+static double
+bump ( double x )
+{
+    x = bump_start + x * (1. - bump_start);
+    if ( x <= 0.) return 0.;
+    if ( x >= 1.) return 1.;
+    x *= (2. - x);
+    x  = (x - 1.) / x;
+    return exp (x * bump_exp);
+}
+
+
+static void
+Fading_In ( PCMDataTyp* data, unsigned int N, const float fs )
+{
+    float  inv_fs = 1.f / fs;
+    float  fadein_pos;
+    float  scale;
+    int    n;
+    int    idx;
+    for ( n = 0; n < BLOCK; n++, N++ ) {
+        idx           = n + CENTER;
+        fadein_pos    = N * inv_fs;
+        scale         = fadein_pos / FadeInTime;
+        scale         = bump (scale);
+        data->L[idx] *= scale;
+        data->R[idx] *= scale;
+        data->M[idx] *= scale;
+        data->S[idx] *= scale;
+    }
+}
+
+
+static void
+Fading_Out ( PCMDataTyp* data, unsigned int N, const float fs )
+{
+    float  inv_fs = 1.f / fs;
+    float  fadeout_pos;
+    float  scale;
+    int    n;
+    int    idx;
+    for ( n = 0; n < BLOCK; n++, N++ ) {
+        idx           = n + CENTER;
+        fadeout_pos   = UintMAX_FP(SamplesInWAVE - N) * inv_fs;
+        scale         = fadeout_pos / FadeOutTime;
+        scale         = bump (scale);
+        data->L[idx] *= scale;
+        data->R[idx] *= scale;
+        data->M[idx] *= scale;
+        data->S[idx] *= scale;
+    }
+}
+
+
+static const unsigned char  Penalty [256] = {
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+      0,  2,  5,  9, 15, 23, 36, 54, 79,116,169,246,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+};
+
+#define P(new,old)  Penalty [128 + (old) - (new)]
+
+static void
+SCF_Extraktion ( PsyModel*m, mpc_encoder_t* e, const int MaxBand, SubbandFloatTyp* x )
+{
+    int    Band;
+    int    n;
+    int    d01;
+    int    d12;
+    int    d02;
+    int    warnL;
+    int    warnR;
+    int*   scfL;
+    int*   scfR;
+    int    comp_L [3];
+    int    comp_R [3];
+    float  tmp_L  [3];
+    float  tmp_R  [3];
+    float  facL;
+    float  facR;
+    float  L;
+    float  R;
+    float  SL;
+    float  SR;
+
+    for ( Band = 0; Band <= MaxBand; Band++ ) {         // Suche nach Maxima
+        L  = FABS (x[Band].L[ 0]);
+        R  = FABS (x[Band].R[ 0]);
+        SL = x[Band].L[ 0] * x[Band].L[ 0];
+        SR = x[Band].R[ 0] * x[Band].R[ 0];
+        for ( n = 1; n < 12; n++ ) {
+            if (L < FABS (x[Band].L[n])) L = FABS (x[Band].L[n]);
+            if (R < FABS (x[Band].R[n])) R = FABS (x[Band].R[n]);
+            SL += x[Band].L[n] * x[Band].L[n];
+            SR += x[Band].R[n] * x[Band].R[n];
+        }
+        Power_L [Band][0] = SL;
+        Power_R [Band][0] = SR;
+        tmp_L [0] = L;
+        tmp_R [0] = R;
+
+        L  = FABS (x[Band].L[12]);
+        R  = FABS (x[Band].R[12]);
+        SL = x[Band].L[12] * x[Band].L[12];
+        SR = x[Band].R[12] * x[Band].R[12];
+        for ( n = 13; n < 24; n++ ) {
+            if (L < FABS (x[Band].L[n])) L = FABS (x[Band].L[n]);
+            if (R < FABS (x[Band].R[n])) R = FABS (x[Band].R[n]);
+            SL += x[Band].L[n] * x[Band].L[n];
+            SR += x[Band].R[n] * x[Band].R[n];
+        }
+        Power_L [Band][1] = SL;
+        Power_R [Band][1] = SR;
+        tmp_L [1] = L;
+        tmp_R [1] = R;
+
+        L  = FABS (x[Band].L[24]);
+        R  = FABS (x[Band].R[24]);
+        SL = x[Band].L[24] * x[Band].L[24];
+        SR = x[Band].R[24] * x[Band].R[24];
+        for ( n = 25; n < 36; n++ ) {
+            if (L < FABS (x[Band].L[n])) L = FABS (x[Band].L[n]);
+            if (R < FABS (x[Band].R[n])) R = FABS (x[Band].R[n]);
+            SL += x[Band].L[n] * x[Band].L[n];
+            SR += x[Band].R[n] * x[Band].R[n];
+        }
+        Power_L [Band][2] = SL;
+        Power_R [Band][2] = SR;
+        tmp_L [2] = L;
+        tmp_R [2] = R;
+
+        // calculation of the scalefactor-indexes
+        // -12.6f*log10(x)+57.8945021823f = -10*log10(x/32767)*1.26+1
+        // normalize maximum of +/- 32767 to prevent quantizer overflow
+        // It can stand a maximum of +/- 32768 ...
+
+        // Where is scf{R,L} [0...2] initialized ???
+        scfL = SCF_Index_L [Band];
+        scfR = SCF_Index_R [Band];
+        if (tmp_L [0] > 0.) scfL [0] = IFLOORF (-12.6f * LOG10 (tmp_L [0]) + 57.8945021823f );
+        if (tmp_L [1] > 0.) scfL [1] = IFLOORF (-12.6f * LOG10 (tmp_L [1]) + 57.8945021823f );
+        if (tmp_L [2] > 0.) scfL [2] = IFLOORF (-12.6f * LOG10 (tmp_L [2]) + 57.8945021823f );
+        if (tmp_R [0] > 0.) scfR [0] = IFLOORF (-12.6f * LOG10 (tmp_R [0]) + 57.8945021823f );
+        if (tmp_R [1] > 0.) scfR [1] = IFLOORF (-12.6f * LOG10 (tmp_R [1]) + 57.8945021823f );
+        if (tmp_R [2] > 0.) scfR [2] = IFLOORF (-12.6f * LOG10 (tmp_R [2]) + 57.8945021823f );
+
+        // restriction to SCF_Index = 0...63, make note of the internal overflow
+        warnL = warnR = 0;
+        if (scfL[0] & ~63) { if (scfL[0] < 0) { if (XLevel==0) scfL[0] = 0, warnL = 1; } else scfL[0] = 63; }
+        if (scfL[1] & ~63) { if (scfL[1] < 0) { if (XLevel==0) scfL[1] = 0, warnL = 1; } else scfL[1] = 63; }
+        if (scfL[2] & ~63) { if (scfL[2] < 0) { if (XLevel==0) scfL[2] = 0, warnL = 1; } else scfL[2] = 63; }
+        if (scfR[0] & ~63) { if (scfR[0] < 0) { if (XLevel==0) scfR[0] = 0, warnR = 1; } else scfR[0] = 63; }
+        if (scfR[1] & ~63) { if (scfR[1] < 0) { if (XLevel==0) scfR[1] = 0, warnR = 1; } else scfR[1] = 63; }
+        if (scfR[2] & ~63) { if (scfR[2] < 0) { if (XLevel==0) scfR[2] = 0, warnR = 1; } else scfR[2] = 63; }
+
+        // save old values for compensation calculation
+        comp_L[0] = scfL[0]; comp_L[1] = scfL[1]; comp_L[2] = scfL[2];
+        comp_R[0] = scfR[0]; comp_R[1] = scfR[1]; comp_R[2] = scfR[2];
+
+        // determination and replacement of scalefactors of minor differences with the smaller one???
+        // a smaller one is quantized more roughly, i.e. the noise gets amplified???
+
+        if ( m->CombPenalities >= 0 ) {
+            if      ( P(scfL[0],scfL[1]) + P(scfL[0],scfL[2]) <= m->CombPenalities ) scfL[2] = scfL[1] = scfL[0];
+            else if ( P(scfL[1],scfL[0]) + P(scfL[1],scfL[2]) <= m->CombPenalities ) scfL[0] = scfL[2] = scfL[1];
+            else if ( P(scfL[2],scfL[0]) + P(scfL[2],scfL[1]) <= m->CombPenalities ) scfL[0] = scfL[1] = scfL[2];
+            else if ( P(scfL[0],scfL[1])                      <= m->CombPenalities ) scfL[1] = scfL[0];
+            else if ( P(scfL[1],scfL[0])                      <= m->CombPenalities ) scfL[0] = scfL[1];
+            else if ( P(scfL[1],scfL[2])                      <= m->CombPenalities ) scfL[2] = scfL[1];
+            else if ( P(scfL[2],scfL[1])                      <= m->CombPenalities ) scfL[1] = scfL[2];
+
+            if      ( P(scfR[0],scfR[1]) + P(scfR[0],scfR[2]) <= m->CombPenalities ) scfR[2] = scfR[1] = scfR[0];
+            else if ( P(scfR[1],scfR[0]) + P(scfR[1],scfR[2]) <= m->CombPenalities ) scfR[0] = scfR[2] = scfR[1];
+            else if ( P(scfR[2],scfR[0]) + P(scfR[2],scfR[1]) <= m->CombPenalities ) scfR[0] = scfR[1] = scfR[2];
+            else if ( P(scfR[0],scfR[1])                      <= m->CombPenalities ) scfR[1] = scfR[0];
+            else if ( P(scfR[1],scfR[0])                      <= m->CombPenalities ) scfR[0] = scfR[1];
+            else if ( P(scfR[1],scfR[2])                      <= m->CombPenalities ) scfR[2] = scfR[1];
+            else if ( P(scfR[2],scfR[1])                      <= m->CombPenalities ) scfR[1] = scfR[2];
+        }
+        else {
+
+            d12  = scfL [2] - scfL [1];
+            d01  = scfL [1] - scfL [0];
+            d02  = scfL [2] - scfL [0];
+
+            if      ( 0 < d12  &&  d12 < 5 ) scfL [2] = scfL [1];
+            else if (-3 < d12  &&  d12 < 0 ) scfL [1] = scfL [2];
+            else if ( 0 < d01  &&  d01 < 5 ) scfL [1] = scfL [0];
+            else if (-3 < d01  &&  d01 < 0 ) scfL [0] = scfL [1];
+            else if ( 0 < d02  &&  d02 < 4 ) scfL [2] = scfL [0];
+            else if (-2 < d02  &&  d02 < 0 ) scfL [0] = scfL [2];
+
+            d12  = scfR [2] - scfR [1];
+            d01  = scfR [1] - scfR [0];
+            d02  = scfR [2] - scfR [0];
+
+            if      ( 0 < d12  &&  d12 < 5 ) scfR [2] = scfR [1];
+            else if (-3 < d12  &&  d12 < 0 ) scfR [1] = scfR [2];
+            else if ( 0 < d01  &&  d01 < 5 ) scfR [1] = scfR [0];
+            else if (-3 < d01  &&  d01 < 0 ) scfR [0] = scfR [1];
+            else if ( 0 < d02  &&  d02 < 4 ) scfR [2] = scfR [0];
+            else if (-2 < d02  &&  d02 < 0 ) scfR [0] = scfR [2];
+        }
+
+        // calculate SNR-compensation
+        tmp_L [0]         = invSCF [comp_L[0] - scfL[0]];
+        tmp_L [1]         = invSCF [comp_L[1] - scfL[1]];
+        tmp_L [2]         = invSCF [comp_L[2] - scfL[2]];
+        tmp_R [0]         = invSCF [comp_R[0] - scfR[0]];
+        tmp_R [1]         = invSCF [comp_R[1] - scfR[1]];
+        tmp_R [2]         = invSCF [comp_R[2] - scfR[2]];
+        m->SNR_comp_L [Band] = (tmp_L[0]*tmp_L[0] + tmp_L[1]*tmp_L[1] + tmp_L[2]*tmp_L[2]) * 0.3333333333f;
+        m->SNR_comp_R [Band] = (tmp_R[0]*tmp_R[0] + tmp_R[1]*tmp_R[1] + tmp_R[2]*tmp_R[2]) * 0.3333333333f;
+
+        // normalize the subband samples
+        facL = invSCF[scfL[0]];
+        facR = invSCF[scfR[0]];
+        for ( n = 0; n < 12; n++ ) {
+            x[Band].L[n] *= facL;
+            x[Band].R[n] *= facR;
+        }
+        facL = invSCF[scfL[1]];
+        facR = invSCF[scfR[1]];
+        for ( n = 12; n < 24; n++ ) {
+            x[Band].L[n] *= facL;
+            x[Band].R[n] *= facR;
+        }
+        facL = invSCF[scfL[2]];
+        facR = invSCF[scfR[2]];
+        for ( n = 24; n < 36; n++ ) {
+            x[Band].L[n] *= facL;
+            x[Band].R[n] *= facR;
+        }
+
+        // limit to +/-32767 if internal clipping
+        if ( warnL )
+            for ( n = 0; n < 36; n++ ) {
+                if      (x[Band].L[n] > +32767.f) {
+                    e->Overflows++;
+                    MaxOverFlow = maxf (MaxOverFlow,  x[Band].L[n]);
+                    x[Band].L[n] = 32767.f;
+                }
+                else if (x[Band].L[n] < -32767.f) {
+					e->Overflows++;
+                    MaxOverFlow = maxf (MaxOverFlow, -x[Band].L[n]);
+                    x[Band].L[n] = -32767.f;
+                }
+            }
+        if ( warnR )
+            for ( n = 0; n < 36; n++ ) {
+                if      (x[Band].R[n] > +32767.f) {
+					e->Overflows++;
+                    MaxOverFlow = maxf (MaxOverFlow,  x[Band].R[n]);
+                    x[Band].R[n] = 32767.f;
+                }
+                else if (x[Band].R[n] < -32767.f) {
+					e->Overflows++;
+                    MaxOverFlow = maxf (MaxOverFlow, -x[Band].R[n]);
+                    x[Band].R[n] = -32767.f;
+                }
+            }
+    }
+    return;
+}
+
+
+static void
+Quantisierung ( PsyModel * m,
+				const int               MaxBand,
+                const int*              resL,
+                const int*              resR,
+                const SubbandFloatTyp*  subx,
+                SubbandQuantTyp*        subq )
+{
+    static float  errorL [32] [36 + MAX_NS_ORDER];
+    static float  errorR [32] [36 + MAX_NS_ORDER];
+    int           Band;
+
+    // quantize Subband- and Subframe-samples
+    for ( Band = 0; Band <= MaxBand; Band++, resL++, resR++ ) {
+
+        if ( *resL > 0 ) {
+            if ( m->NS_Order_L [Band] > 0 ) {
+                QuantizeSubbandWithNoiseShaping ( subq[Band].L, subx[Band].L, *resL, errorL [Band], m->FIR_L [Band] );
+                memcpy ( errorL [Band], errorL[Band] + 36, MAX_NS_ORDER * sizeof (**errorL) );
+            } else {
+				QuantizeSubband                 ( subq[Band].L, subx[Band].L, *resL, errorL [Band], MAX_NS_ORDER );
+                memcpy ( errorL [Band], errorL[Band] + 36, MAX_NS_ORDER * sizeof (**errorL) );
+            }
+        }
+
+        if ( *resR > 0 ) {
+            if ( m->NS_Order_R [Band] > 0 ) {
+                QuantizeSubbandWithNoiseShaping ( subq[Band].R, subx[Band].R, *resR, errorR [Band], m->FIR_R [Band] );
+                memcpy ( errorR [Band], errorR [Band] + 36, MAX_NS_ORDER * sizeof (**errorL) );
+            } else {
+				QuantizeSubband                 ( subq[Band].R, subx[Band].R, *resR, errorL [Band], MAX_NS_ORDER);
+                memcpy ( errorR [Band], errorR [Band] + 36, MAX_NS_ORDER * sizeof (**errorL) );
+            }
+        }
+    }
+    return;
+}
+
+
+static int
+PNS_SCF ( int* scf, float S0, float S1, float S2 )
+{
+//    printf ("%7.1f %7.1f %7.1f  ", sqrt(S0/12), sqrt(S1/12), sqrt(S2/12) );
+
+#if 1
+    if ( S0 < 0.5 * S1  ||  S1 < 0.5 * S2  ||  S0 < 0.5 * S2 )
+        return 0;
+
+    if ( S1 < 0.25 * S0  ||  S2 < 0.25 * S1  ||  S2 < 0.25 * S0 )
+        return 0;
+#endif
+
+
+    if ( S0 >= 0.8 * S1 ) {
+        if ( S0 >= 0.8 * S2  &&  S1 > 0.8 * S2 )
+            S0 = S1 = S2 = 0.33333333333f * (S0 + S1 + S2);
+        else
+            S0 = S1 = 0.5f * (S0 + S1);
+    }
+    else {
+        if ( S1 >= 0.8 * S2 )
+            S1 = S2 = 0.5f * (S1 + S2);
+    }
+
+    scf [0] = scf [1] = scf [2] = 63;
+    S0 = sqrt (S0/12 * 4/1.2005080577484075047860806747022);
+    S1 = sqrt (S1/12 * 4/1.2005080577484075047860806747022);
+    S2 = sqrt (S2/12 * 4/1.2005080577484075047860806747022);
+    if (S0 > 0.) scf [0] = IFLOORF (-12.6f * LOG10 (S0) + 57.8945021823f );
+    if (S1 > 0.) scf [1] = IFLOORF (-12.6f * LOG10 (S1) + 57.8945021823f );
+    if (S2 > 0.) scf [2] = IFLOORF (-12.6f * LOG10 (S2) + 57.8945021823f );
+
+    if ( scf[0] & ~63 ) scf[0] = scf[0] > 63 ? 63 : 0;
+    if ( scf[1] & ~63 ) scf[1] = scf[1] > 63 ? 63 : 0;
+    if ( scf[2] & ~63 ) scf[2] = scf[2] > 63 ? 63 : 0;
+
+    return 1;
+}
+
+
+static void
+Allocate ( const int MaxBand, int* res, float* x, int* scf, const float* comp, const float* smr, const SCFTriple* Pow, const int* Transient, const float PNS )
+{
+    int    Band;
+    int    k;
+    float  tmpMNR;      // to adjust the scalefactors
+    float  save [36];   // to adjust the scalefactors
+    float  MNR;         // Mask-to-Noise ratio
+
+    for ( Band = 0; Band <= MaxBand; Band++, res++, comp++, smr++, scf += 3, x += 72 ) {
+        // printf ( "%2u: %u\n", Band, Transient[Band] );
+
+        // Find out needed quantization resolution Res to fulfill the calculated MNR
+        // This is done by exactly measuring the quantization residuals against the signal itself
+        // Starting with Res=1  Res in increased until MNR becomes less than 1.
+        if ( Band > 0  &&  res[-1] < 3  &&  *smr >= 1. &&  *smr < Band * PNS  &&
+             PNS_SCF ( scf, Pow [Band][0], Pow [Band][1], Pow [Band][2] ) ) {
+            *res = -1;
+        } else {
+            for ( MNR = *smr * 1.; MNR > 1.  &&  *res != 15; )
+                MNR = *smr * (Transient[Band] ? ISNR_Schaetzer_Trans : ISNR_Schaetzer) ( x, *comp, ++*res );
+        }
+
+        // Fine adapt SCF's (MNR > 0 prevents adaption of zero samples, which is nonsense)
+        // only apply to Huffman-coded samples (otherwise no savings in bitrate)
+        if ( *res > 0  &&  *res <= LAST_HUFFMAN  &&  MNR < 1.  &&  MNR > 0.  &&  !Transient[Band] ) {
+            while ( scf[0] > 0  &&  scf[1] > 0  &&  scf[2] > 0 ) {
+
+                --scf[2]; --scf[1]; --scf[0];                   // adapt scalefactors and samples
+                memcpy ( save, x, sizeof save );
+                for (k = 0; k < 36; k++ )
+                    x[k] *= SCFfac;
+
+                tmpMNR = *smr * (Transient[Band] ? ISNR_Schaetzer_Trans : ISNR_Schaetzer) ( x, *comp, *res );// recalculate MNR
+
+                // FK: if ( tmpMNR > MNR  &&  tmpMNR <= 1 ) {          // check for MNR
+                if ( tmpMNR <= 1 ) {                            // check for MNR
+                    MNR = tmpMNR;
+                }
+                else {
+                    ++scf[0]; ++scf[1]; ++scf[2];               // restore scalefactors and samples
+                    memcpy ( x, save, sizeof save );
+                    break;
+                }
+            }
+        }
+
+    }
+    return;
+}
+
+
+
+
+/* Planned: return the evaluated options, without InputFile and OutputFile, argc implicit instead of explicit */
+
+static int
+EvalParameters (PsyModel * m, int argc, char** argv, char** InputFile, char** OutputFile, int onlyfilenames )
+{
+    int          k;
+    size_t       len;
+    static char  output [2048];
+    static char  errmsg [] = "\n\033[33;41;1mERROR\033[0m: Missing argument for option '--%s'\n\n";
+    FILE*        fp;
+    char*        p;
+    char         buff [32768];
+
+    /********************************* In / Out Files *********************************/
+    *InputFile  = argv [argc-1];
+    *OutputFile = NULL;
+
+    // search for output file
+    if ( argc >= 3 ) {
+        len = strlen (argv[argc-1]);
+
+        if ( strcmp (argv[argc-1], "/dev/null") == 0  ||
+             strcmp (argv[argc-1], "-")         == 0  ||
+             (len >= 4  &&  (0 == strcasecmp (argv [argc-1] + len - 4, ".MPC")  ||
+                             0 == strcasecmp (argv [argc-1] + len - 4, ".MPP")  ||
+                             0 == strcasecmp (argv [argc-1] + len - 4, ".MP+"))) ) {
+            *OutputFile = argv[argc-1];
+            *InputFile  = argv[argc-2];
+            argc -= 2;
+        }
+    }
+
+    // if no Output-File is stated, set OutFile to InFile.mpc
+    if ( *OutputFile == NULL  ) {
+        strcpy ( *OutputFile = output, *InputFile );
+        len = strlen ( output );
+        if ( len > 4  &&  output[len-4] == '.' )
+            len -= 4;
+        strcpy (output+len, ".mpc");
+        argc -= 1;
+    }
+
+    if ( onlyfilenames )
+        return 0;
+
+    /********************************* In / Out Files *********************************/
+
+
+    // search for options
+    for ( k = 1; k < argc; k++ ) {
+
+        const char*  arg = argv [k];
+
+        if ( arg[0] != '-'  ||  arg[1] != '-' )
+            continue;
+        arg += 2;
+
+        if      ( 0 == strcmp ( arg, "verbose" ) ) {                                     // verbose
+            verbose++;
+        }
+        else if ( 0 == strcmp ( arg, "telephone" ) ) {                                   // MainQual
+            SetQualityParams (m, 2.0);
+        }
+        else if ( 0 == strcmp ( arg, "thumb" ) ) {                                       // MainQual
+            SetQualityParams (m, 3.0);
+        }
+        else if ( 0 == strcmp ( arg, "radio"   ) ) {
+            SetQualityParams (m, 4.0);
+        }
+        else if ( 0 == strcmp ( arg, "standard")  ||  0 == strcmp ( arg, "normal") ) {
+            SetQualityParams (m, 5.0);
+        }
+        else if ( 0 == strcmp ( arg, "xtreme")  ||  0 == strcmp ( arg, "extreme") ) {
+            SetQualityParams (m, 6.0);
+        }
+        else if ( 0 == strcmp ( arg, "insane") ) {
+            SetQualityParams (m, 7.0);
+        }
+        else if ( 0 == strcmp ( arg, "braindead") ) {
+            SetQualityParams (m, 8.0);
+        }
+        else if ( 0 == strcmp ( arg, "quality") ) {                                      // Quality
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            SetQualityParams (m, atof (argv[k]) );
+        }
+        else if ( 0 == strcmp ( arg, "neveroverwrite") ) {                              // NeverOverWrite
+            WriteMode = MODE_NEVER_OVERWRITE;
+        }
+        else if ( 0 == strcmp ( arg, "forcewrite")  ||  0 == strcmp ( arg, "overwrite") ) { // ForceWrite
+            WriteMode = MODE_OVERWRITE;
+        }
+        else if ( 0 == strcmp ( arg, "interactive")  ) {                                // Interactive
+            WriteMode = MODE_ASK_FOR_OVERWRITE;
+        }
+        else if ( 0 == strcmp ( arg, "delinput")  ||  0 == strcmp ( arg, "delete")  ||  0 == strcmp ( arg, "deleteinput" ) ) {                                    // DelInput
+            DelInput = 0xAFFEDEAD;
+        }
+        else if ( 0 == strcmp ( arg, "beep")  ) {
+            IsEndBeep = TRUE;
+        }
+        else if ( 0 == strcmp ( arg, "scale") ) {                                       // ScalingFactor
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            ScalingFactorl = ScalingFactorr = (float) atof (argv[k]);
+            if (strchr (argv[k], ','))
+                ScalingFactorr = (float) atof (strchr (argv[k], ',') + 1);
+            if ( ScalingFactorl == 0.97f  ||  ScalingFactorl == 0.98f ) stderr_printf ("--scale 0.97 or --scale 0.98 is nearly useless to prevent clipping. Use replaygain tool\nto determine EXACT attenuation to avoid clipping. Factor can be between 0.696 and 1.000.\nSee \"http://www.uni-jena.de/~pfk/mpp/clipexample.html\".\n\n" );
+        }
+        else if ( 0 == strcmp ( arg, "kbd") ) {                                       // ScalingFactor
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+			if ( 2 != sscanf ( argv[k], "%f,%f", &(m->KBD1), &(m->KBD2) ))
+                { stderr_printf ( "%s: missing two arguments", arg ); return -1; }
+            Init_FFT (m);
+        }
+        else if ( 0 == strcmp ( arg, "fadein") ) {                                      // FadeInTime
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            FadeInTime = (float) atof (argv[k]);
+            if ( FadeInTime < 0.f ) FadeInTime = 0.f;
+        }
+        else if ( 0 == strcmp ( arg, "fadeout") ) {                                     // FadeOutTime
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            FadeOutTime = (float) atof (argv[k]);
+            if ( FadeOutTime < 0.f ) FadeOutTime = 0.f;
+        }
+        else if ( 0 == strcmp ( arg, "fade") ) {                                        // FadeInTime + FadeOutTime
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            FadeOutTime = (float) atof (argv[k]);
+            if ( FadeOutTime < 0.f ) FadeOutTime = 0.f;
+            FadeInTime = FadeOutTime;
+        }
+        else if ( 0 == strcmp ( arg, "fadeshape") ) {                                   // FadeOutTime
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            FadeShape = (float) atof (argv[k]);
+            if ( FadeShape < 0.001f  ||  FadeShape > 1000.f ) FadeShape = 1.f;
+            setbump ( FadeShape );
+        }
+        else if ( 0 == strcmp ( arg, "skip")  ||  0 == strcmp ( arg, "start") ) {       // SkipTime
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            SkipTime = (float) atof (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "dur")  ||  0 == strcmp ( arg, "duration") ) {     // maximum Duration
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            Duration = atof (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "ans") ) {                                         // AdaptiveNoiseShaping
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            m->NS_Order = atoi (argv[k]);
+            m->NS_Order = mini ( m->NS_Order, MAX_NS_ORDER );
+        }
+        else if ( 0 == strcmp ( arg, "predict") ) {                                     // AdaptiveNoiseShaping
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            PredictionBands = atoi (argv[k]);
+            PredictionBands = mini ( PredictionBands, 32 );
+        }
+        else if ( 0 == strcmp ( arg, "ltq_var")  ||  0 == strcmp ( arg, "ath_var") ) {  // ltq_var
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            m->varLtq = atof (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "pns") ) {                                         // pns
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            m->PNS = atof (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "minval") ) {                                      // MinValChoice
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            m->MinValChoice = atoi (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "transdet") ) {                                    // TransDetect
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            m->TransDetect = (float) atof (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "shortthr") ) {                                    // ShortThr
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            m->ShortThr = (float) atof (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "noxlevel") ) {                                      // Xlevel
+            XLevel = 0;
+        }
+        else if ( 0 == strcmp ( arg, "xlevel") ) {                                      // Xlevel
+            stderr_printf ( "\nXlevel coding now enabled by default, --xlevel ignored.\n" );
+        }
+        else if ( 0 == strcmp ( arg, "nmt") ) {                                         // NMT
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg );  return -1; }
+            m->NMT = (float) atof (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "tmn") ) {                                         // TMN
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg );  return -1; }
+            m->TMN = (float) atof (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "cvd") ) {                                         // ClearVoiceDetection
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            m->CVD_used = atoi (argv[k]);
+            if ( m->CVD_used == 0 )
+                stderr_printf ( "\nDisabling CVD always reduces quality!\a\n" );
+        }
+        else if ( 0 == strcmp ( arg, "ms") ) {                                          // Mid/Side Stereo
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            m->MS_Channelmode = atoi (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "minSMR") ) {                                      // minimum SMR
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            if ( m->minSMR > (float) atof (argv[k]) )
+                stderr_printf ( "This option usage may reduces quality!\a\n" );
+            m->minSMR = (float) atof (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "tmpMask") ) {                                     // temporal post-masking
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            m->tmpMask_used = atoi (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "ltq_max")  ||  0 == strcmp ( arg, "ath_max") ) {  // Maximum for threshold in quiet
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg );  return -1; }
+			m->Ltq_max = (float) atof (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "ltq_gain")  ||  0 == strcmp ( arg, "ath_gain") ) {// Offset for threshold in quiet
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+			m->Ltq_offset = (float) atof (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "silent")  ||  0 == strcmp ( arg, "quiet") ) {
+            SetStderrSilent (1);
+        }
+        else if ( 0 == strcmp ( arg, "stderr") ) {                                      // Offset for threshold in quiet
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            freopen ( argv[k], "a", stderr );
+        }
+        else if ( 0 == strcmp ( arg, "ltq")  ||  0 == strcmp ( arg, "ath") ) {          // threshold in quiet
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            m->EarModelFlag = atoi (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "noco") ) {
+            NoiseInjectionComp ();
+        }
+        else if ( 0 == strcmp ( arg, "newcomb") ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            m->CombPenalities = atoi (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "ape1") ) {                                     // Mark APE as APE 1.000
+            APE_Version = 1000;
+        }
+        else if ( 0 == strcmp ( arg, "ape2") ) {                                     // Mark APE as APE 2.000
+            APE_Version = 2000;
+        }
+        else if ( 0 == strcmp ( arg, "unicode") ) {                                  // no tag conversion
+            NoUnicode = 0;
+        }
+        else if ( 0 == strcmp ( arg, "writetags") ) {
+            EnableTags = TRUE;
+        }
+        else if ( 0 == strcmp ( arg, "lowdelay") ) {
+            LowDelay = 1;
+        }
+        else if ( 0 == strcmp ( arg, "bw")  ||  0 == strcmp ( arg, "lowpass") ) {       // bandwidth
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+			m->BandWidth = atof (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "displayupdatetime") ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            DisplayUpdateTime = atoi (argv[k]);
+        }
+        else if ( 0 == strcmp ( arg, "artist" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Artist", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "album" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Album", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "debutalbum" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Debut Album", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "publisher" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Publisher", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "conductor" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Conductor", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "title" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Title", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "subtitle" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Subtitle", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "track" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Track", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "comment" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Comment", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "composer" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Composer", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "copyright" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Copyright", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "publicationright" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Publicationright", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "filename" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "File", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "recordlocation" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Record Location", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "recorddate" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Record Date", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "ean/upc" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "EAN/UPC", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "year" )  ||  0 == strcmp ( arg, "releasedate") ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Year", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "genre" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Genre", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "media" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Media", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "index" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Index", 0, p, strlen(p), NoUnicode*3, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "isrc" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "ISRC", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "abstract" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Abstract", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "bibliography" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Bibliography", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "introplay" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Introplay", 0, p, strlen(p), NoUnicode*3, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "media" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = argv[k];
+            addtag ( "Media", 0, p, strlen(p), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "tag" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = strchr ( argv[k], '=' );
+            if ( p == NULL )
+                addtag ( argv[k], strlen(argv[k]), "", 0, NoUnicode, 0 );
+            else
+                addtag ( argv[k], p-argv[k], p+1, strlen(p+1), NoUnicode, 0 );
+        }
+        else if ( 0 == strcmp ( arg, "tagfile" ) ) {
+            if ( ++k >= argc ) { stderr_printf ( errmsg, arg ); return -1; }
+            p = strchr ( argv[k], '=' );
+            if ( p == NULL ) {
+                stderr_printf (" Enter value for tag key '%s': ", argv[k] );
+                fgets ( buff, sizeof buff, stdin );
+                len = strlen (buff);
+                while ( len > 0  &&  (buff [len-1] == '\r'  ||  buff [len-1] == '\n') )
+                    len--;
+                addtag ( arg, strlen(arg), buff, len, NoUnicode*6, 0 );
+            }
+            else {
+                fp = fopen ( p+1, "rb" );
+                if ( fp == NULL ) {
+                    fprintf ( stderr, "Can't open file '%s'.\n", p+1 );
+                }
+                else {
+                    addtag ( argv[k], p-argv[k], buff, fread (buff,1,sizeof buff,fp), NoUnicode*2, 3 );
+                    fclose (fp);
+                }
+            }
+        }
+        else {
+            char c;
+            stderr_printf ( "\n\033[33;41;1mERROR\033[0m: unknown option '--%s' !\n", arg );
+
+            stderr_printf ( "\nNevertheless continue with encoding (Y/n)? \a" );
+            c = waitkey ();
+            if ( c != 'Y' && c != 'y' ) {
+                stderr_printf ( "\n\n*** Abort ***\n" );
+                return -1;
+            }
+            stderr_printf ( "\n" );
+        }
+    }
+
+    TestProfileParams (m);
+    return 0;
+}
+
+
+static void
+ShowParameters (PsyModel * m, char* inDatei, char* outDatei )
+{
+    static const char        unk      []       = "???";
+    static const char*       EarModel []       = { "ISO (bad!!!)", "Busch", "Filburt", "Klemm", "Klemm/Busch mix", "min(Klemm,Busch)" };
+    static const char        th       [ 7] [4] = { "no", "1st", "2nd", "3rd", "4th", "5th", "6th" };
+    static const char        able     [ 3] [9] = { "Disabled", "Enabled", "Dual" };
+    static const char*       stereo   [16]     = {
+        "Simple uncoupled Stereo",
+        "Mid/Side Stereo + Intensity Stereo 2 bit",
+        "Mid/Side Stereo + Intensity Stereo 4 bit",
+        "Mid/Side Stereo, destroyed imaging (unusable)",
+        "Mid/Side Stereo, much reduced imaging",
+        "Mid/Side Stereo, reduced imaging (-3 dB)",
+        "Mid/Side Stereo when superior",
+        unk, unk, unk,
+        "Mid/Side Stereo when superior + enhanced (1.5/3 dB)",
+        "Mid/Side Stereo when superior + enhanced (2/6 dB)",
+        "Mid/Side Stereo when superior + enhanced (2.5/9 dB)",
+        "Mid/Side Stereo when superior + enhanced (3/12 dB)",
+        unk,
+        "Mid/Side Stereo when superior + enhanced (3/oo dB)"
+    };
+    static const char* const Profiles [16]     = {
+        "n.a", "Unstable/Experimental", unk, unk, unk, "below Telephone", "below Telephone", "Telephone",
+        "Thumb", "Radio", "Standard", "Xtreme", "Insane", "BrainDead", "above BrainDead", "above BrainDead"
+    };
+
+    stderr_printf ( "\n"
+                    " encoding file '%s'\n"
+                    "       to file '%s'\n"
+                    "\n"
+                    " SV %u.%u%s, Profile '%s'\n",
+                    inDatei, outDatei, 7, m->PNS > 0 ? 1 : 0, XLevel ? " + XLevel coding" : "", Profiles [m->MainQual] );
+
+    if ( verbose > 0 ) {
+        stderr_printf ( "\n" );
+        if ( FadeInTime != 0.  ||  FadeOutTime != 0.  ||  verbose > 1 )
+            stderr_printf ( " PCM fader                : fade-in: %.2f s, fade-out: %.2f s, shape: %g\n", FadeInTime, FadeOutTime, FadeShape );
+        if ( ScalingFactorr != 1.  ||  ScalingFactorl != 1.  ||  verbose > 1 )
+            stderr_printf ( " Scaling input by         : left %.5f, right: %.5f\n", ScalingFactorl, ScalingFactorr );
+        stderr_printf ( " Maximum encoded bandwidth: %4.1f kHz\n", (m->Max_Band+1) * (m->SampleFreq/32./2000.) );
+        stderr_printf ( " Adaptive Noise Shaping   : max. %s order\n", th [m->NS_Order] );
+        stderr_printf ( " Clear Voice Detection    : %s\n", able [m->CVD_used] );
+        stderr_printf ( " Mid/Side Stereo          : %s\n", stereo [m->MS_Channelmode] );
+        stderr_printf ( " Threshold of Hearing     : Model %3u: %s, Max ATH: %2.0f dB, Offset: %+1.0f dB, +Offset@20 kHz:%3.0f dB\n",
+                        m->EarModelFlag,
+						m->EarModelFlag/100 < sizeof(EarModel)/sizeof(*EarModel) ? EarModel [m->EarModelFlag/100] : unk,
+                        m->Ltq_max,
+                        m->Ltq_offset,
+                        -0.6 * (int) (m->EarModelFlag % 100 - 50) );
+		if ( m->NMT !=  6.5 || verbose > 1 )
+			stderr_printf ( " Noise masks Tone Ratio   : %4.1f dB\n", m->NMT );
+		if ( m->TMN != 18.0 || verbose > 1 )
+			stderr_printf ( " Tone masks Noise Ratio   : %4.1f dB\n", m->TMN );
+        if ( m->PNS > 0 )
+            stderr_printf ( " PNS Threshold            : %4.2f\n", m->PNS );
+		if ( !m->tmpMask_used )
+            stderr_printf ( " No exploitation of temporal post masking\n" );
+        else if ( verbose > 1 )
+            stderr_printf ( " Exploitation of temporal post masking\n" );
+		if ( m->minSMR > 0. )
+			stderr_printf ( " Minimum Signal-to-Mask   : %4.1f dB\n", m->minSMR );
+        else if ( verbose > 1 )
+            stderr_printf ( " No minimum SMR (psycho model controlled filtering)\n" );
+        if ( DelInput == 0xAFFEDEAD )
+            stderr_printf ( " Deleting input file after (successful) encoding\n" );
+        else if ( verbose > 1 )
+            stderr_printf ( " No deleting of input file after encoding\n" );
+    }
+    stderr_printf ( "\n" );
+}
+
+
+/*
+ *  Print out the time to stderr with a precision of 10 ms always using
+ *  12 characters. Time is represented by the sample count. An additional
+ *  prefix character (normally ' ' or '-') is prepended before the first
+ *  digit.
+ */
+
+static const char*
+PrintTime ( PsyModel* m, UintMax_t samples, int sign )
+{
+    static char  ret [32];
+	Ulong        tmp  = (Ulong) ( UintMAX_FP(samples) * 100. / m->SampleFreq );
+    Uint         hour = (Uint)  ( tmp / 360000     );
+    Uint         min  = (Uint)  ( tmp / 6000 %  60 );
+    Uint         sec  = (Uint)  ( tmp / 100  %  60 );
+    Uint         csec = (Uint)  ( tmp        % 100 );
+
+
+	if ( UintMAX_FP(samples) >= m->SampleFreq * 360000. )
+        return "            ";
+    else if ( hour > 9 )
+        sprintf ( ret,  "%c%2u:%02u", sign, hour, min );
+    else if ( hour > 0 )
+        sprintf ( ret, " %c%1u:%02u", sign, hour, min );
+    else if ( min  > 9 )
+        sprintf ( ret,    "   %c%2u", sign,       min );
+    else
+        sprintf ( ret,   "    %c%1u", sign,       min );
+
+    sprintf ( ret + 6,   ":%02u.%02u", sec, csec );
+    return ret;
+}
+
+
+static void
+ShowProgress ( PsyModel* m,
+			   UintMax_t  samples,
+               UintMax_t  total_samples,
+               UintMax_t  databits )
+{
+    static clock_t  start;
+    clock_t         curr;
+    float           percent;
+    float           kbps;
+    float           speed;
+    float           total_estim;
+
+    if ( samples == 0 ) {
+        if ( DisplayUpdateTime >= 0 ) {
+            stderr_printf ("    %%|avg.bitrate| speed|play time (proc/tot)| CPU time (proc/tot)| ETA\n"
+                            "  -.-    -.- kbps  -.--x     -:--.-    -:--.-     -:--.-    -:--.-     -:--.-\r" );
+        }
+        start = clock ();
+        return;
+    }
+    curr    = clock ();
+    if ( curr == start )
+        return;
+
+    percent     = 100.f    * UintMAX_FP(samples) / UintMAX_FP(total_samples);
+	kbps        =   1.e-3f * UintMAX_FP(databits) * m->SampleFreq / UintMAX_FP(samples);
+	speed       =   1.f    * UintMAX_FP(samples) * (CLOCKS_PER_SEC / m->SampleFreq) / (unsigned long)(curr - start) ;
+    total_estim =   1.f    * UintMAX_FP(total_samples) / UintMAX_FP(samples) * (unsigned long)(curr - start);
+
+    // progress percent
+    if ( total_samples < IntMax_MAX )
+        stderr_printf ("\r%5.1f ", percent );
+    else
+        stderr_printf ("\r      " );
+
+    // average data rate
+    stderr_printf ( "%6.1f kbps ", kbps );
+
+    // encoder speed
+    stderr_printf ( "%5.2fx ", speed );
+
+    // 2x duration in WAVE file time (encoded/total)
+    stderr_printf ("%10.10s" , PrintTime ( m, samples      , (char)' ')+1 );
+    stderr_printf ("%10.10s ", PrintTime ( m, total_samples, (char)' ')+1 );
+
+    // 2x coding time (encoded/total)
+	stderr_printf ("%10.10s" , PrintTime ( m, (curr - start) * (m->SampleFreq/CLOCKS_PER_SEC), (char)' ')+1 );
+	stderr_printf ("%10.10s ", PrintTime ( m, total_estim    * (m->SampleFreq/CLOCKS_PER_SEC), (char)' ')+1 );
+
+    // ETA
+	stderr_printf ( "%10.10s\r", samples < total_samples  ?  PrintTime (m, (total_estim - curr + start) * (m->SampleFreq/CLOCKS_PER_SEC), (char)' ')+1  :  "" );
+    fflush ( stderr );
+
+    if ( WIN32_MESSAGES  &&  FrontendPresent )
+        SendProgressMessage ( kbps, speed, percent );
+}
+
+
+static int
+myfeof ( FILE* fp )
+{
+    int  ch;
+
+    if ( fp != (FILE*)-1 )
+        return feof (fp);
+
+    ch = CheckKeyKeep ();
+    if ( ch == 'q'  ||  ch == 'Q' )
+        return 1;
+    return 0;
+}
+
+static void fill_float(float * buffer,float val,unsigned count)
+{
+	unsigned n;
+	for(n=0;n<count;n++) buffer[n] = val;
+}
+
+
+static void OverdriveReport ( mpc_encoder_t * e )
+{
+	if ( e->Overflows > 0 ) {                                                // report internal clippings
+		if ( XLevel == 0 ) {
+			stderr_printf ( "\n"
+					"\033[1m\rWARNING:\n"
+					"\033[0m\r  There occured %u internal clippings due to a restriction of StreamVersion 7.\n"
+					"  Re-encode with '--scale %.3f', or use option '--xlevel', which normally can\n"
+					"  handle this situation but don't work well with old decoders.\a\n\n",
+			e->Overflows, ScalingFactorl * 32767. / MaxOverFlow - 0.0005f );
+		}
+		else {
+			stderr_printf ( "\n"
+					"\033[1m\rWARNING:\n"
+					"\033[0m\r  There still occured %u SCF clippings due to a restriction of StreamVersion 7.\n"
+					"  Use the '--scale' method to avoid additional distortions. Note that this\n"
+					"  file already has annoying distortions due to slovenly CD mastering.\a\n\n", e->Overflows );
+		}
+	}
+}
+
+// FIXME : not sure if it's a good idea
+#include <fpu_control.h>
+
+static void Init_FPU ( void )
+{
+	mpc_uint16_t  cw;
+
+#if   defined __i386__  &&  defined _FPU_GETCW  &&  defined _FPU_SETCW
+    _FPU_GETCW ( cw );
+    cw  &=  ~0x300;
+	_FPU_SETCW ( cw );
+#elif defined __i386__  &&  defined  FPU_GETCW  &&  defined  FPU_SETCW
+    FPU_GETCW ( cw );
+    cw  &=  ~0x300;
+	FPU_SETCW ( cw );
+#elif defined __MINGW32__
+    __asm__ ("fnstcw %0" : "=m" (*&cw));
+    cw  &=  ~0x300;
+	__asm__ ("fldcw %0" : : "m" (*&cw));
+#elif defined(_WIN32) && !defined(_WIN64)
+    _asm { fstcw cw };
+    cw  &=  ~0x300;
+	_asm { fldcw cw };
+#else
+    ;
+#endif
+}
+
+static FILE * OpenStream(char * OutputName)
+{
+	FILE * OutputFile = NULL;
+
+	/* open bitstream file */
+	if      ( 0 == strcmp ( OutputName, "/dev/null") )
+		OutputFile = fopen (DEV_NULL, "wb");
+	else if ( 0 == strcmp ( OutputName, "-")  ||  0 == strcmp ( OutputName, "/dev/stdout") )
+		OutputFile = SETBINARY_OUT (stdout);
+	else
+		switch ( WriteMode ) {
+			default:
+				stderr_printf ( "\033[33;41;1mERROR\033[0m: Invalid Write mode, internal error\n" );
+				exit(1);
+			case MODE_NEVER_OVERWRITE:
+				OutputFile = fopen ( OutputName, "rb" );
+				if ( OutputFile != NULL ) {
+					fclose ( OutputFile );
+					stderr_printf ( "\033[33;41;1mERROR\033[0m: Output file '%s' already exists\n", OutputName );
+					exit(1);
+				}
+				OutputFile = fopen ( OutputName, "w+b" );
+				break;
+			case MODE_OVERWRITE:
+				OutputFile = fopen ( OutputName, "w+b" );
+				break;
+			case MODE_ASK_FOR_OVERWRITE:
+				OutputFile = fopen ( OutputName, "rb" );
+				if ( OutputFile != NULL ) {
+					char c;
+					fclose ( OutputFile );
+					stderr_printf ( "\nmppenc: Output file '%s' already exists, overwrite (Y/n)? ", OutputName );
+					c = waitkey ();
+					if ( c != 'Y'  &&  c != 'y' ) {
+						stderr_printf ( "No!!!\n\n*** Canceled overwrite ***\n" );
+						exit(1);
+					}
+					stderr_printf ( " YES\n" );
+				}
+				OutputFile = fopen ( OutputName, "w+b" );
+				break;
+		}
+
+	if ( OutputFile == NULL ) {
+		stderr_printf ( "\033[33;41;1mERROR\033[0m: Could not create output file '%s'\n", OutputName );
+		exit(1);
+	}
+	return OutputFile;
+}
+
+static int
+mainloop ( int argc, char** argv )
+{
+    SMRTyp           SMR;                       // contains SMRs for the given frame
+    PCMDataTyp       Main;                      // contains PCM data for 1600 samples
+    SubbandFloatTyp  X [32];                    // Subbandsamples as float()
+    SubbandQuantTyp  Q [32];                    // Subband samples after quantization
+    wave_t           Wave;                      // contains WAV-files arguments
+    UintMax_t        AllSamplesRead   =    0;   // overall read Samples per channel
+    unsigned int     CurrentRead      =    0;   // current read Samples per channel
+    unsigned int     N;                         // counter for processed frames
+    char*            InputName        = NULL;   // Name of WAVE file
+    char*            OutputName       = NULL;   // Name of bitstream file
+    int              Silence          =    0;
+    int              OldSilence       =    0;
+    time_t           T;
+    int              TransientL [PART_SHORT];   // Flag of transient detection
+    int              TransientR [PART_SHORT];   // Flag of transient detection
+    int              Transient  [32];           // Flag of transient detection
+	PsyModel         m;
+	mpc_encoder_t    e;
+
+    // initialize tables which must be initialized once and only once
+
+	m.SCF_Index_L = (int*) SCF_Index_L;
+	m.SCF_Index_R = (int*) SCF_Index_R;
+
+	Init_Psychoakustik (&m);
+	Init_FPU ();
+	Init_SV8 (&e);
+
+    // initialize PCM-data
+    memset ( &Main, 0, sizeof Main );
+
+    // open WAV file
+    if ( EvalParameters (&m,  argc, argv, &InputName, &OutputName, 1 ) < 0 )
+        return 1;
+    if ( Open_WAV_Header ( &Wave, InputName ) < 0 ) {
+        stderr_printf ( "\033[33;41;1mERROR\033[0m: Unable to read or decode: '%s'\n", InputName );
+        return 1;
+    }
+    TitleBar ( InputName );
+    CopyTags ( InputName );
+
+    // read WAV-Header
+    if ( 0 != Read_WAV_Header (&Wave) ) {
+        stderr_printf ( "\033[33;41;1mERROR\033[0m: Invalid file header, not a WAVE file '%s'\n", InputName );
+        return 1;
+    }
+
+    m.SampleFreq = Wave.SampleFreq;
+    SamplesInWAVE = Wave.PCMSamples;
+
+    if ( Wave.SampleFreq != 44100.  &&  Wave.SampleFreq != 48000.  &&  Wave.SampleFreq != 37800.  &&  Wave.SampleFreq != 32000. ) {
+        stderr_printf ( "\033[33;41;1mERROR\033[0m: Sampling frequency of %g kHz is not supported!\n\n", (double)(Wave.SampleFreq * 1.e-3) );
+        return 1;
+    }
+
+    if ( Wave.BitsPerSample < 8  ||  Wave.BitsPerSample > 32 ) {
+        stderr_printf ( "\033[33;41;1mERROR\033[0m: %i bits per sample are not supported!\n\n", Wave.BitsPerSample );
+        return 1;
+    }
+
+    switch ( Wave.Channels ) {
+    case  0:
+        stderr_printf ( "\033[33;41;1mERROR\033[0m: 0 channels file, this is nonsense\n\n" );
+        return 1;
+    case  1: case  2:
+        break;
+    case  3: case  4: case  5: case  6: case  7: case  8:
+        stderr_printf ( "WARNING: %i channel(s) file, only first 2 channels are encoded.\n\n", Wave.Channels );
+        break;
+    default:
+        stderr_printf ( "\033[33;41;1mERROR\033[0m: %i channel(s) file, not supported\n\n", Wave.Channels );
+        return 1;
+    }
+
+    SetQualityParams (&m, 5.0);
+
+    if ( EvalParameters (&m, argc, argv, &InputName, &OutputName, 0 ) < 0 )
+        return 1;
+
+    if ( UintMAX_FP(SamplesInWAVE) >= Wave.SampleFreq * (SkipTime + Duration) ) {
+        SamplesInWAVE = Wave.SampleFreq * (SkipTime + Duration);
+    }
+
+    Init_Psychoakustiktabellen (&m);              // must be done AFTER decoding command line parameters
+
+    // check fade-length
+    if ( FadeInTime + FadeOutTime > UintMAX_FP(SamplesInWAVE) / Wave.SampleFreq ) {
+        stderr_printf ( "WARNING: Duration of fade in + out exceeds file length!\n");
+        FadeInTime = FadeOutTime = 0.5 * UintMAX_FP(SamplesInWAVE) / Wave.SampleFreq;
+    }
+
+	e.outputFile = OpenStream(OutputName);
+
+    ShowParameters (&m, InputName, OutputName );
+    if ( WIN32_MESSAGES  &&  FrontendPresent )
+        SendModeMessage (MainQual);
+
+    if ( SkipTime > 0. ) {
+        unsigned long  SkipSamples = m.SampleFreq * SkipTime;
+        ssize_t        read;
+
+        while ( SkipSamples > 0 ) {
+            read          = Read_WAV_Samples ( &Wave, mini(BLOCK, SkipSamples), &Main, CENTER, ScalingFactorl, ScalingFactorr, &Silence );
+            if ( read <= 0 )
+                break;
+            SkipSamples   -= read;
+            SamplesInWAVE -= read;
+        }
+    }
+
+	e.MS_Channelmode = m.MS_Channelmode;
+//     e.BufferedBits     = 0;
+	writeMagic(&e);
+	writeStreamInfo ( &e, m.Max_Band, m.MS_Channelmode > 0, SamplesInWAVE,
+					   m.SampleFreq, Wave.Channels > 2 ? 2 : Wave.Channels);
+	writeBlock(&e, "SI", TRUE);
+	writeGainInfo(&e);
+	writeBlock(&e, "RG", FALSE);
+	writeEncoderInfo(&e, m.MainQual, m.PNS > 0, MPPENC_MAJOR, MPPENC_MINOR,
+					  MPPENC_IMPLEMENT, MPPENC_BUILD);
+	writeBlock(&e, "EI", FALSE);
+
+    // initialize timer
+    ShowProgress (&m, 0, SamplesInWAVE, e.outputBits );
+    T            = time ( NULL );
+
+    // read samples
+    CurrentRead     = Read_WAV_Samples ( &Wave, (int)minf(BLOCK, SamplesInWAVE - AllSamplesRead), &Main, CENTER, ScalingFactorl, ScalingFactorr, &Silence );
+    AllSamplesRead += CurrentRead;
+
+	if (CurrentRead > 0)
+	{
+		fill_float( Main.L, Main.L[CENTER], CENTER );
+		fill_float( Main.R, Main.R[CENTER], CENTER );
+		fill_float( Main.M, Main.M[CENTER], CENTER );
+		fill_float( Main.S, Main.S[CENTER], CENTER );
+	}
+
+	Analyse_Init ( Main.L[CENTER], Main.R[CENTER], X, m.Max_Band );
+
+    // adapt SamplesInWAVE to the real number of contained samples
+    if ( myfeof (Wave.fp) ) {
+        stderr_printf ( "WAVE file has incorrect header: header: %.3f s, contents: %.3f s    \n",
+						UintMAX_FP(AllSamplesRead) / m.SampleFreq, UintMAX_FP(SamplesInWAVE) / m.SampleFreq );
+        SamplesInWAVE = AllSamplesRead;
+    }
+
+    for ( N = 0; (UintMax_t)N * BLOCK < SamplesInWAVE + DECODER_DELAY; N++ ) {
+
+        // setting residual data-fields to zero
+        if ( CurrentRead < BLOCK  &&  N > 0 ) {
+            fill_float( Main.L + (CENTER + CurrentRead), Main.L[CENTER + CurrentRead - 1], BLOCK - CurrentRead );
+            fill_float( Main.R + (CENTER + CurrentRead), Main.R[CENTER + CurrentRead - 1], BLOCK - CurrentRead );
+            fill_float( Main.M + (CENTER + CurrentRead), Main.M[CENTER + CurrentRead - 1], BLOCK - CurrentRead );
+            fill_float( Main.S + (CENTER + CurrentRead), Main.S[CENTER + CurrentRead - 1], BLOCK - CurrentRead );
+        }
+
+        /*********************************************************************************/
+        /*                                Fade In and Fade Out                                */
+        /*********************************************************************************/
+        if ( FadeInTime  > 0. )
+            if ( FadeInTime  > UintMAX_FP(BLOCK         + (UintMax_t)N*BLOCK) / Wave.SampleFreq )
+                Fading_In  ( &Main, N*BLOCK, Wave.SampleFreq );
+        if ( FadeOutTime > 0. )
+            if ( FadeOutTime > UintMAX_FP(SamplesInWAVE - (UintMax_t)N*BLOCK) / Wave.SampleFreq )
+                Fading_Out ( &Main, N*BLOCK, Wave.SampleFreq );
+
+        /********************************************************************/
+        /*                         Encoder-Core                             */
+        /********************************************************************/
+        // you only get null samples at the output of the filterbank when the last frame contains zeroes
+
+        memset ( Res_L, 0, sizeof Res_L );
+        memset ( Res_R, 0, sizeof Res_R );
+
+        if ( !Silence  ||  !OldSilence ) {
+            Analyse_Filter ( &Main, X, m.Max_Band );                      // Analysis-Filterbank (Main -> X)
+			SMR = Psychoakustisches_Modell (&m, m.Max_Band*0+31, &Main, TransientL, TransientR );    // Psychoacoustics return SMRs for input data 'Main'
+            if ( m.minSMR > 0 )
+				RaiseSMR (&m, m.Max_Band, &SMR );                            // Minimum-operation on SBRs (full bandwidth)
+			if ( m.MS_Channelmode > 0 )
+				MS_LR_Entscheidung ( m.Max_Band, MS_Flag, &SMR, X );      // Selection of M/S- or L/R-Coding
+			SCF_Extraktion (&m, &e, m.Max_Band, X );                             // Extraction of the scalefactors and normalization of the subband samples
+            TransientenCalc ( Transient, TransientL, TransientR );
+			if ( m.NS_Order > 0 ) {
+				NS_Analyse (&m, m.Max_Band, MS_Flag, SMR, Transient );                  // calculate possible ANS-Filter and the expected gain
+            }
+
+            Allocate ( m.Max_Band, Res_L, X[0].L, SCF_Index_L[0], m.SNR_comp_L, SMR.L, Power_L, Transient , m.PNS );   // allocate bits for left + right channel
+			Allocate ( m.Max_Band, Res_R, X[0].R, SCF_Index_R[0], m.SNR_comp_R, SMR.R, Power_R, Transient , m.PNS );
+
+			Quantisierung (&m, m.Max_Band, Res_L, Res_R, X, Q );             // quantize samples
+        }
+
+        OldSilence      = Silence;
+        WriteBitstream_SV7 ( &e, m.Max_Band, Q );                                                // write SV7-Bitstream
+
+        if ( (Int)(time (NULL) - T) >= 0 ) {                            // output
+            T += labs (DisplayUpdateTime);
+			ShowProgress (&m, (UintMax_t)(N+1) * BLOCK, SamplesInWAVE, e.outputBits );
+        }
+
+        // for backwards-compatibility with older decoders write the 11 bit for
+        // reconstruction of exact filelength before the very last frame
+
+        memmove ( Main.L, Main.L + BLOCK, CENTER * sizeof(float) );
+        memmove ( Main.R, Main.R + BLOCK, CENTER * sizeof(float) );
+        memmove ( Main.M, Main.M + BLOCK, CENTER * sizeof(float) );
+        memmove ( Main.S, Main.S + BLOCK, CENTER * sizeof(float) );
+
+        // read samples
+        CurrentRead     = Read_WAV_Samples ( &Wave, (int)minf(BLOCK, SamplesInWAVE - AllSamplesRead), &Main, CENTER, ScalingFactorl, ScalingFactorr, &Silence );
+        AllSamplesRead += CurrentRead;
+
+        // adapt SamplesInWAV to the real number of contained samples
+        if ( myfeof (Wave.fp) ) {
+            stderr_printf ( "WAVE file has incorrect header: header: %.3f s, contents: %.3f s    \n",
+							UintMAX_FP(AllSamplesRead) / m.SampleFreq, UintMAX_FP(SamplesInWAVE) / m.SampleFreq );
+            SamplesInWAVE = AllSamplesRead;
+        }
+    }
+
+    // write the last incomplete block
+	writeBlock(&e, "AD", FALSE);
+	writeBlock(&e, "SE", FALSE); // write end of stream block
+    ShowProgress (&m, SamplesInWAVE, SamplesInWAVE, e.outputBits );
+
+    if(EnableTags)
+        FinalizeTags ( e.outputFile, APE_Version );
+    fclose ( e.outputFile );
+    fclose ( Wave.fp );
+
+    if ( DelInput == 0xAFFEDEAD  &&  remove (InputName) == -1 )         // delete input file if DelInput is active
+        stderr_printf ( "\n\n\033[33;41;1mERROR\033[0m: Could not delete input file '%s'\n", InputName );
+
+    if ( WIN32_MESSAGES  &&  FrontendPresent )
+        SendQuitMessage ();
+
+    stderr_printf ( "\n" );
+
+	OverdriveReport (&e);                         // output a report if clipping was necessary
+
+    return 0;
+}
+
+
+/************ The main() function *****************************/
+int Cdecl
+main ( int argc, char** argv )
+{
+    int  ret;
+
+#if (defined USE_OSS_AUDIO  ||  defined USE_ESD_AUDIO  ||  defined USE_SUN_AUDIO)  &&  (defined USE_REALTIME  ||  defined USE_NICE)
+    // DisableSUID ();
+#endif
+
+#ifdef _OS2
+    _wildcard ( &argc, &argv );
+#endif
+
+    if ( WIN32_MESSAGES ) {
+        FrontendPresent = SearchForFrontend (); // search for presence of Windows Frontend
+        if ( FrontendPresent )
+            SendStartupMessage ( MPPENC_VERSION, 8);
+    }
+
+    // Welcome message
+    if ( argc < 2  ||  ( 0 != strcmp (argv[1], "--silent")  &&  0 != strcmp (argv[1], "--quiet")) )
+        (void) stderr_printf ("\r\x1B[1m\r%s\n\x1B[0m\r     \r", About );
+
+    // no arguments or call for help
+    if ( argc < 2  ||  0==strcmp (argv[1],"-h")  ||  0==strcmp (argv[1],"-?")  ||  0==strcmp (argv[1],"--help") ) {
+		PsyModel m;
+        SetQualityParams (&m, 5.0);
+        dup2 ( 1, 2 );
+        shorthelp ();
+        return 1;
+    }
+
+    if ( 0==strcmp (argv[1],"--longhelp")  ||  0==strcmp (argv[1],"-??") ) {
+		PsyModel m;
+        SetQualityParams (&m, 5.0);
+        dup2 ( 1, 2 );
+        longhelp (&m);
+        return 1;
+    }
+
+    ret = mainloop ( argc, argv );              // analyze command line and do the requested work
+
+    if(IsEndBeep)
+        stderr_printf("\a\a\a");
+
+#ifdef BUGBUG
+    reppr ();
+#endif
+    return ret;
+}
+
+/* end of mppenc.c */
Index: /libmpc/branches/r2d/mppenc/mppenc.h
===================================================================
--- /libmpc/branches/r2d/mppenc/mppenc.h	(revision 133)
+++ /libmpc/branches/r2d/mppenc/mppenc.h	(revision 133)
@@ -0,0 +1,194 @@
+/*
+ * Musepack audio compression
+ * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf
+ *
+ * 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
+ */
+
+#ifndef MPPENC_MPPENC_H
+#define MPPENC_MPPENC_H
+
+#ifdef _WIN32
+# define CVD_FASTLOG
+#endif
+
+#include "libmpcenc.h"
+#include "libmpcpsy.h"
+#include "datatypes.h"
+#include "minimax.h"
+
+#include "mppdec.h"
+
+#define WIN32_MESSAGES      1                   // support Windows-Messaging to Frontend
+
+// analyse_filter.c
+#define X_MEM            1152
+
+// quant.h
+#define SCFfac              0.832980664785f     // = SCF[n-1]/SCF[n]
+
+// wave_in.h
+
+typedef struct {
+    FILE*         fp;                   // File pointer to read data
+    Ulong         PCMOffset;            // File offset of PCM data
+    long double   SampleFreq;           // Sample frequency in Hz
+    Uint          BitsPerSample;        // used bits per sample, 8*BytesPerSample-7 <= BitsPerSample <= BytesPerSample
+    Uint          BytesPerSample;       // allocated bytes per sample
+    Uint          Channels;             // Number of channels, 1...8
+    UintMax_t     PCMBytes;             // PCM Samples (in 8 bit units)
+    UintMax_t     PCMSamples;           // PCM Samples per Channel
+    Bool_t        raw;                  // raw: headerless format
+} wave_t;
+
+// FIXME : put in lib header
+
+void   Init_FFT      ( PsyModel* );
+
+// FIXME : put in lib header
+void   Init_Psychoakustik       ( PsyModel* );
+SMRTyp Psychoakustisches_Modell ( PsyModel *, const int, const PCMDataTyp*, int* TransientL, int* TransientR );
+void   TransientenCalc          ( int* Transient, const int* TransientL, const int* TransientR );
+void   RaiseSMR                 ( PsyModel*, const int, SMRTyp* );
+void   MS_LR_Entscheidung       ( const int, unsigned char* MS, SMRTyp*, SubbandFloatTyp* );
+void   Init_Psychoakustiktabellen ( PsyModel* );
+
+void   NS_Analyse (PsyModel*, const int, const unsigned char* MS, const SMRTyp, const int* Transient );
+
+void   Analyse_Filter(const PCMDataTyp*, SubbandFloatTyp*, const int);
+void   Analyse_Init ( float Left, float Right, SubbandFloatTyp* out, const int MaxBand );
+
+void SetQualityParams (PsyModel *, float );
+int TestProfileParams ( PsyModel* );
+
+extern const float  Butfly    [7];              // Antialiasing to calculate the subband powers
+extern const float  InvButfly [7];              // Antialiasing to calculate the masking thresholds
+extern const float  iw        [PART_LONG];      // inverse partition-width for long
+extern const float  iw_short  [PART_SHORT];     // inverse partition-width for short
+extern const int    wl        [PART_LONG];      // w_low  for long
+extern const int    wl_short  [PART_SHORT];     // w_low  for short
+extern const int    wh        [PART_LONG];      // w_high for long
+extern const int    wh_short  [PART_SHORT];     // w_high for short
+
+
+// quant.c
+extern float __invSCF [128 + 6];        // tabulated scalefactors (inverted)
+#define invSCF  (__invSCF + 6)
+
+float  ISNR_Schaetzer                  ( const float* samples, const float comp, const int res);
+float  ISNR_Schaetzer_Trans            ( const float* samples, const float comp, const int res);
+void   QuantizeSubband                 ( unsigned int* qu_output, const float* input, const int res, float* errors, const int maxNsOrder );
+void   QuantizeSubbandWithNoiseShaping ( unsigned int* qu_output, const float* input, const int res, float* errors, const float* FIR );
+
+void   NoiseInjectionComp ( void );
+
+
+// FIXME : no more globals
+// encode_sv7.c
+extern unsigned char  MS_Flag     [32];                  // subband-wise mid/side flag
+extern int            Res_L       [32];
+extern int            Res_R       [32];                  // resolution steps of the subbands
+extern int            SCF_Index_L [32] [3];
+extern int            SCF_Index_R [32] [3];              // Scalefactor-index for Bitstream
+
+// FIXME : put in lib header
+void         Init_SV8             ( mpc_encoder_t* );
+void writeStreamInfo ( mpc_encoder_t*e,
+					   const unsigned int  MaxBand,
+					   const unsigned int  MS_on,
+					   const unsigned int  SamplesCount,
+					   const unsigned int  SampleFreq,
+					   const unsigned int  ChannelCount);
+void writeEncoderInfo ( mpc_encoder_t * e,
+						const int profile,
+						const int PNS_on,
+						const int version_major,
+						const int version_minor,
+						const int version_implement,
+						const int version_build );
+void writeGainInfo ( mpc_encoder_t * e );
+void writeBlock ( mpc_encoder_t * e, const char * key, const mpc_bool_t addCRC);
+void writeMagic(mpc_encoder_t * e);
+void         WriteBitstream_SV7   ( mpc_encoder_t*, const int, const SubbandQuantTyp* );
+
+
+
+
+void    Huffman_SV7_Encoder ( void );
+
+
+// keyboard.c
+int    WaitKey      ( void );
+int    CheckKeyKeep ( void );
+int    CheckKey     ( void );
+
+
+// regress.c
+void    Regression       ( float* const _r, float* const _b, const float* p, const float* q );
+
+
+// tags.c
+void    Init_Tags        ( void );
+int     FinalizeTags     ( FILE* fp, unsigned int Version );
+int     addtag           ( const char* key, size_t keylen, const char* value, size_t valuelen, int converttoutf8, int flags );
+int     gettag           ( const char* key, char* dst, size_t len );
+int     CopyTags         ( const char* filename );
+
+
+// wave_in.c
+int     Open_WAV_Header  ( wave_t* type, const char* name );
+size_t  Read_WAV_Samples ( wave_t* t, const size_t RequestedSamples, PCMDataTyp* data, const ptrdiff_t offset, const float scalel, const float scaler, int* Silence );
+int     Read_WAV_Header  ( wave_t* type );
+
+
+// winmsg.c
+#ifdef _WIN32
+int    SearchForFrontend   ( void );
+void   SendQuitMessage     ( void );
+void   SendModeMessage     ( const int );
+void   SendStartupMessage  ( const char*, const int);
+void   SendProgressMessage ( const int, const float, const float );
+#else
+# undef  WIN32_MESSAGES
+# define WIN32_MESSAGES                 0
+# define SearchForFrontend()            (0)
+# define SendQuitMessage()              (void)0
+# define SendModeMessage(x)             (void)0
+# define SendStartupMessage(x,y)        (void)0
+# define SendProgressMessage(x,y,z)     (void)0
+#endif /* _WIN32 */
+
+
+#define MPPENC_DENORMAL_FIX_BASE ( 32. * 1024. /* normalized sample value range */ / ( (float) (1 << 24 /* first bit below 32-bit PCM range */ ) ) )
+#define MPPENC_DENORMAL_FIX_LEFT ( MPPENC_DENORMAL_FIX_BASE )
+#define MPPENC_DENORMAL_FIX_RIGHT ( MPPENC_DENORMAL_FIX_BASE * 0.5f )
+
+
+#endif /* MPPENC_MPPENC_H */
+
+#if 0
+# define LAST_HUFFMAN   15
+# define DUMP_HIGHRES
+#endif
+
+#if 0
+# define DUMP_RES15
+#endif
+
+#ifndef LAST_HUFFMAN
+# define LAST_HUFFMAN    7
+#endif
+
+/* end of mppenc.h */
Index: /libmpc/branches/r2d/mppenc/pipeopen.c
===================================================================
--- /libmpc/branches/r2d/mppenc/pipeopen.c	(revision 133)
+++ /libmpc/branches/r2d/mppenc/pipeopen.c	(revision 133)
@@ -0,0 +1,195 @@
+/*
+ *  Opens a communication channel to another program using unnamed pipe mechanism and stdin/stdout.
+ *
+ *  (C) Frank Klemm 2001,02. All rights reserved.
+ *
+ *  Principles:
+ *
+ *  History:
+ *    2001          created
+ *    2002
+ *
+ *  Global functions:
+ *    - pipeopen
+ *
+ *  TODO:
+ *    -
+ */
+
+//#define DEBUG2
+
+#include "mppdec.h"
+#include <ctype.h>
+
+
+/*
+ *
+ */
+
+static int
+EscapeProgramPathName ( const char*  longprogname,
+                        char*        escaped,
+                        size_t       len )
+{
+    int   ret = 0;
+
+#ifdef _WIN32
+    ret = GetShortPathName ( longprogname, escaped, len );
+#else
+    if ( strlen (longprogname) <= len-3 )
+        ret = sprintf ( escaped, "\"%s\"", longprogname );      // Note that this only helps against spaces and some similar things in the file name, not against all strange stuff
+#endif
+
+    if ( ret <= 0  ||  ret >= (int)len ) {
+    }
+
+    return ret;
+}
+
+
+/*
+ *
+ */
+
+static FILE*
+OpenPipeWhenBinaryExist ( const char*  path,
+                          size_t       pathlen,
+                          const char*  executable_filename,
+                          const char*  command_line )
+{
+    char   filename [4096];
+    char   cmdline  [4096];
+    char*  p  = filename;
+    FILE*  fp;
+
+    for ( ; *path  &&  pathlen--; path++ )
+        if ( *path != '"' )
+            *p++ = *path;
+    *p++ = PATH_SEP;
+    strcpy ( p, executable_filename );
+#ifdef DEBUG2
+    stderr_printf ("Test for file »%s«        \n", filename );
+#endif
+    fp = fopen ( filename, "rb" );
+    if ( fp != NULL ) {
+        fclose ( fp );
+        EscapeProgramPathName ( filename, cmdline, sizeof cmdline );
+        strcat ( cmdline, command_line );
+        fp = POPEN_READ_BINARY_OPEN ( cmdline );
+#ifdef DEBUG2
+        stderr_printf ("Executed »%s«\n", cmdline );
+#endif
+   }
+   return fp;
+}
+
+
+/*
+ *
+ */
+
+static FILE*
+TracePathList ( const char*  p,
+                const char*  executable_filename,
+                const char*  command_line )
+{
+    const char*  nextsep;
+    FILE*        fp;
+
+    while ( p != NULL   &&  *p != '\0' ) {
+        if ( (nextsep = strchr (p, ENVPATH_SEP)) == NULL ) {
+            fp = OpenPipeWhenBinaryExist ( p, (size_t)         -1, executable_filename, command_line );
+            p  = NULL;
+        }
+        else {
+            fp = OpenPipeWhenBinaryExist ( p, (size_t)(nextsep-p), executable_filename, command_line );
+            p  = nextsep + 1;
+        }
+        if ( fp != NULL )
+            return fp;
+    }
+    return NULL;
+}
+
+
+/*
+ *  Executes command line given by »command«.
+ *  The command must be found in some predefined paths or in the ${PATH} aka %PATH%
+ *  The char »#« in command is replaced by the contents
+ *  of »filename«. Special characters are escaped.
+ */
+
+FILE*
+pipeopen ( const char* command, const char* filename )
+{
+    static const char  pathlist [] =
+#ifdef _WIN32
+        ".";
+#else
+        "/usr/bin:/usr/local/bin:/opt/mpp:.";
+#endif
+    char          command_line        [4096];           // » -o - bar.pac«
+    char          executable_filename [4096];           // »foo.exe«
+    char*         p;
+    const char*   q;
+    FILE*         fp;
+
+    // does the source file exist and is readble?
+    if ( (fp = fopen (filename, "rb")) == NULL ) {
+        stderr_printf ("file '%s' not found.\n", filename );
+        return NULL;
+    }
+    fclose (fp);
+
+    // extract executable name from the 'command' to executable_filename, append executable extention
+    p = executable_filename;
+    for ( ; *command != ' '  &&  *command != '\0'; command++ )
+        *p++ = *command;
+    strcpy ( p, EXE_EXT );
+
+
+    // Copy 'command' to 'command_line' replacing '#' by filename
+    p = command_line;
+    for ( ; *command != '\0'; command++ ) {
+        if ( *command != '#' ) {
+            *p++ = *command;
+        }
+        else {
+            q = filename;
+            if (*q == '-') {
+                *p++ = '.';
+                *p++ = PATH_SEP;
+            }
+#ifdef _WIN32                           // Windows secure Way to "escape"
+            *p++ = '"';
+            while (*q)
+                *p++ = *q++;
+            *p++ = '"';
+#else                                   // Unix secure Way to \e\s\c\a\p\e
+            while (*q) {
+                if ( !isalnum(*q)  &&  *q != '.'  &&  *q != '-'  &&  *q != '_'  &&  *q != '/' )
+                    *p++ = '\\';
+                *p++ = *q++;
+            }
+#endif
+        }
+    }
+    *p = '\0';
+
+    // Try the several built-in paths to find binary
+    fp = TracePathList ( pathlist       , executable_filename, command_line );
+    if ( fp != NULL )
+        return fp;
+
+    // Try the PATH settings to find binary (Why we must search for the executable in all PATH settings? --> popen itself do not return useful information)
+    fp = TracePathList ( getenv ("PATH"), executable_filename, command_line );
+    if ( fp != NULL )
+        return fp;
+
+#ifdef DEBUG2
+    stderr_printf ("Nothing found to execute.\n" );
+#endif
+    return NULL;
+}
+
+/* end of pipeopen.c */
Index: /libmpc/branches/r2d/mppenc/predict.h
===================================================================
--- /libmpc/branches/r2d/mppenc/predict.h	(revision 133)
+++ /libmpc/branches/r2d/mppenc/predict.h	(revision 133)
@@ -0,0 +1,176 @@
+/*
+ * Musepack audio compression
+ * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf
+ *
+ * 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
+ */
+
+#include "mppenc.h"
+
+
+#define MAX_LPC_ORDER       35
+#define log2(x)             ( log (x) * (1./M_LN2) )
+#define ORDER_PENALTY       0
+
+
+static int                                     // best prediction order model
+CalculateLPCCoeffs ( Int32_t*  buf,            // Samples
+                     size_t    nbuf,           // Number of samples
+                     Int32_t   offset,         //
+                     double*   lpcout,         // quantized prediction coefficients
+                     int       nlpc,           // max. prediction order
+                     float*    psigbit,        // expected number of bits per original signal sample
+                     float*    presbit )       // expected number of bits per residual signal sample
+{
+    static double*  fbuf  = NULL;
+    static int      nflpc = 0;
+    static int      nfbuf = 0;
+    int             nbit;
+    int             i;
+    int             j;
+    int             bestnbit;
+    int             bestnlpc;
+    double          e;
+    double          bestesize;
+    double          ci;
+    double          esize;
+    double          acf [MAX_LPC_ORDER + 1];
+    double          ref [MAX_LPC_ORDER + 1];
+    double          lpc [MAX_LPC_ORDER + 1];
+    double          tmp [MAX_LPC_ORDER + 1];
+    double          escale = 0.5 * M_LN2 * M_LN2 / nbuf;
+    double          sum;
+
+    if ( nlpc >= nbuf )                         // if necessary, limit the LPC order to the number of samples available
+        nlpc = nbuf - 1;
+
+    if ( nlpc > nflpc  ||  nbuf > nfbuf ) {     // grab some space for a 'zero mean' buffer of floats if needed
+        if ( fbuf != NULL )
+            free ( fbuf - nflpc );
+        fbuf  = nlpc + ((double*) calloc ( nlpc+nbuf, sizeof (*fbuf) ));
+        nfbuf = nbuf;
+        nflpc = nlpc;
+    }
+
+    e = 0.;
+    for ( j = 0; j < nbuf; j++ ) {              // zero mean signal and compute energy
+        sum = fbuf [j] = buf[j] - (double)offset;
+        e  += sum * sum;
+    }
+
+    esize     = e > 0.  ?  0.5 * log2 (escale * e)  :  0.;
+    *psigbit  = esize;                          // return the expected number of bits per original signal sample
+
+    acf [0]   = e;                              // store the best values so far (the zeroth order predictor)
+    bestnlpc  = 0;
+    bestnbit  = nbuf * esize;
+    bestesize = esize;
+
+    for ( i = 1; i <= nlpc  &&  e > 0.  &&  i < bestnlpc + 4; i++ ) {   // just check two more than bestnlpc
+
+        sum = 0.;
+        for ( j = i; j < nbuf; j++ )                                    // compute the jth autocorrelation coefficient
+            sum += fbuf [j] * fbuf [j-i];
+        acf [i] = sum;
+
+        ci = 0.;                                                        // compute the reflection and LP coeffients for order j predictor
+        for ( j = 1; j < i; j++ )
+            ci += lpc [j] * acf [i-j];
+        lpc [i] = ref [i] = ci = (acf [i] - ci) / e;
+        for ( j = 1; j < i; j++ )
+            tmp [j] = lpc [j] - ci * lpc [i-j];
+        for ( j = 1; j < i; j++ )
+            lpc [j] = tmp [j];
+
+        e    *= 1 - ci*ci;                                              // compute the new energy in the prediction residual
+        esize = e > 0.  ?  0.5 * log2 (escale * e)  :  0.;
+
+        nbit = nbuf * esize + i * ORDER_PENALTY;
+        if ( nbit < bestnbit ) {                                        // store this model if it is the best so far
+            bestnlpc  = i;                                              // store best model order
+            bestnbit  = nbit;
+            bestesize = esize;
+
+            for ( j = 0; j < bestnlpc; j++ )                            // store the quantized LP coefficients
+                lpcout [j] = lpc [j+1];
+        }
+    }
+
+    *presbit = bestesize;                       // return the expected number of bits per residual signal sample
+    return bestnlpc;                            // return the best model order
+}
+
+
+static void
+Pred ( const unsigned int*  new,
+       unsigned int*        old )
+{
+    static Double  DOUBLE [36];
+    Float   org;
+    Float   pred;
+    int     i;
+    int     j;
+    int     sum = 18;
+    int     order;
+    double  oldeff = 0.;
+    double  neweff = 0.;
+
+    for ( i = 0; i < 36; i++ )
+        sum += old [i];
+    sum = (int) floor (sum / 36.);
+
+    order = CalculateLPCCoeffs ( old, 36, sum*0, DOUBLE, 35, &org, &pred );
+
+    printf ("avg: %4u  [%2u]  %.2f  %.2f\n\n", sum, order, org, pred );
+    if ( order < 1 )
+        return;
+
+    for ( i = 0; i < order; i++ )
+        printf ("%f ", DOUBLE[i] );
+    printf ("\n");
+
+    for ( i = 0; i < 36; i++ ) {
+        double  sum = 0.;
+        for ( j = 1; j <= order; j++ ) {
+            sum += (i-j < 0 ? old[i-j+36] : new [i-j]) * DOUBLE [j-1];
+        }
+        printf ("%2u: %6.2f %3d\n", i, sum, new [i] );
+        oldeff += new[i]       * new[i];
+        neweff += (sum-new[i]) * (sum-new[i]);
+    }
+    printf ("%6.2f %6.2f\n", sqrt(oldeff), sqrt(neweff) );
+}
+
+
+void
+Predicate ( int Channel, int Band, unsigned int* x, int* scf )
+{
+    static Int32_t  OLD [2] [32] [36];
+    int    i;
+
+    printf ("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
+    for ( i = 0; i < 36; i++ )
+        printf ("%2d ", OLD [Channel][Band][i] );
+    printf ("\n");
+    for ( i = 0; i < 36; i++ )
+        printf ("%2d ", x[i] );
+    printf ("\n");
+    printf ("%2u-%2u-%2u  ", scf[0], scf[1], scf[2] );
+    Pred ( x, OLD [Channel][Band] );
+    for ( i = 0; i < 36; i++ )
+        OLD [Channel][Band][i] = x[i];
+}
+
+/* end of predict.c */
Index: /libmpc/branches/r2d/mppenc/stderr.c
===================================================================
--- /libmpc/branches/r2d/mppenc/stderr.c	(revision 133)
+++ /libmpc/branches/r2d/mppenc/stderr.c	(revision 133)
@@ -0,0 +1,180 @@
+/*
+ *  stderr - Message output system
+ *
+ *  (C) Frank Klemm, Janne Hyvärinen 2002. All rights reserved.
+ *
+ *  Principles:
+ *
+ *  History:
+ *    2001              created
+ *    2002 Spring       added functionality to switch on and off printing to easily allow silent modes
+ *    2002-10-10        Escape sequence handling for Windows added.
+ *
+ *  Global functions:
+ *    - SetStderrSilent()
+ *    - GetStderrSilent()
+ *    - stderr_printf()
+ *
+ *  TODO:
+ *    -
+ */
+
+#include "mppdec.h"
+#ifdef _WIN32
+# include <windows.h>
+#endif
+
+
+static Bool_t  stderr_silent = 0;
+
+
+void
+SetStderrSilent ( Bool_t state )
+{
+    stderr_silent = state;
+}
+
+
+Bool_t
+GetStderrSilent ( void )
+{
+    return stderr_silent;
+}
+
+
+int Cdecl
+stderr_printf ( const char* format, ... )
+{
+    char     buff [2 * PATHLEN_MAX + 3072];
+    char*    p = buff;
+    char*    q;
+    int      ret;
+    va_list  v;
+
+    /* print to a buffer */
+    va_start ( v, format );
+    ret = vsprintf ( p, format, v );
+    va_end ( v );
+
+    if ( !stderr_silent ) {
+
+#if   defined __unix__  ||  defined __UNIX__
+
+        WRITE ( STDERR, buff, ret );
+
+#elif defined _WIN32
+
+# define FOREGROUND_ALL         ( FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED )
+# define BACKGROUND_ALL         ( BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED )
+
+        // for Windows systems we must merge carriage returns into the stream to avoid staircases
+        // Also escape sequences must be detected and replaced (incomplete now)
+
+        char                            buff [128];
+        static int                      init = 0;
+        CONSOLE_SCREEN_BUFFER_INFO      con_info;
+        static HANDLE                   hSTDERR;
+        static WORD                     attr;
+        static WORD                     attr_initial;
+        DWORD                           written;
+
+        if ( init == 0 ) {
+            hSTDERR = GetStdHandle ( STD_ERROR_HANDLE );
+            attr    = hSTDERR == INVALID_HANDLE_VALUE  ||  GetConsoleScreenBufferInfo ( hSTDERR, &con_info ) == 0
+                      ?  FOREGROUND_ALL  :  con_info.wAttributes;
+            attr_initial = attr;
+            init    = 1;
+        }
+
+        if ( hSTDERR == INVALID_HANDLE_VALUE ) {
+            while ( ( q = strchr (p, '\n')) != NULL ) {
+                WRITE ( STDERR, p, q-p );
+                WRITE ( STDERR, "\r\n", 2 );
+                p = q+1;
+            }
+            WRITE ( STDERR, p, strlen (p) );
+        }
+        else {
+            for ( ; *p; p++ ) {
+                switch ( *p ) {
+                case '\n':
+                    SetConsoleTextAttribute ( hSTDERR, attr_initial );
+                    fprintf ( stderr, "\r\n" );
+                    SetConsoleTextAttribute ( hSTDERR, attr );
+                    break;
+
+                case '\x1B':
+                    if ( p[1] == '[' ) {
+                        unsigned int  tmp;
+
+                        p++;
+                cont:   p++;
+                        for ( tmp = 0; (unsigned int)( *p - '0' ) < 10u; p++ )
+                            tmp = 10 * tmp + ( *p - '0' );
+
+                        switch ( *p ) {
+                        case ';':
+                        case 'm':
+                            switch ( tmp ) {
+                            case  0: attr  =  FOREGROUND_ALL;                                                   break; // reset defaults
+                            case  1: attr |=  FOREGROUND_INTENSITY;                                             break; // high intensity on
+                            case  2: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_INTENSITY;                     break; // (very) low intensity
+                            case  3:                                                                            break; // italic on
+                            case  4:                                                                            break; // underline on
+                            case  5:                                                                            break; // blinking on
+                            case  7:                                                                            break; // reverse
+                            case  8: attr  =  0;                                                                break; // invisible
+                            case 30: attr &= ~FOREGROUND_ALL;                                                   break;
+                            case 31: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_RED;                           break;
+                            case 32: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_GREEN;                         break;
+                            case 33: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_RED | FOREGROUND_GREEN;        break;
+                            case 34: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_BLUE;                          break;
+                            case 35: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_RED | FOREGROUND_BLUE;         break;
+                            case 36: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_GREEN | FOREGROUND_BLUE;       break;
+                            case 37: case 39:                 attr |= FOREGROUND_ALL;                           break;
+                            case 40: case 49:
+                                     attr &= ~BACKGROUND_ALL;                                                   break;
+                            case 41: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_RED;                           break;
+                            case 42: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_GREEN;                         break;
+                            case 43: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_RED | BACKGROUND_GREEN;        break;
+                            case 44: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_BLUE;                          break;
+                            case 45: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_RED | BACKGROUND_BLUE;         break;
+                            case 46: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_GREEN | BACKGROUND_BLUE;       break;
+                            case 47:                          attr |= BACKGROUND_ALL;                           break;
+                            }
+                            SetConsoleTextAttribute ( hSTDERR, attr );
+                            if ( *p == ';' )
+                                goto cont;
+                            break;
+
+                        default:
+                            WriteFile ( hSTDERR, buff, sprintf ( buff, "Unknown escape sequence ending with '%c'\n", *p ), &written, NULL );
+                            break;
+                        }
+                        break;
+                    }
+                default:
+                    fputc ( *p, stderr );
+                    break;
+                }
+            } /* end for */
+        }
+
+#else
+
+        // for non-Unix systems we must merge carriage returns into the stream to avoid staircases
+        while ( ( q = strchr (p, '\n')) != NULL ) {
+            WRITE ( STDERR, p, q-p );
+            WRITE ( STDERR, "\r\n", 2 );
+            p = q+1;
+        }
+        WRITE ( STDERR, p, strlen (p) );
+
+#endif
+
+    }
+
+    return ret;
+}
+
+/* end of stderr.c */
Index: /libmpc/branches/r2d/mppenc/tags.c
===================================================================
--- /libmpc/branches/r2d/mppenc/tags.c	(revision 133)
+++ /libmpc/branches/r2d/mppenc/tags.c	(revision 133)
@@ -0,0 +1,1332 @@
+/*
+ *  Encoder tag handling
+ *
+ *  (C) Frank Klemm 2002. Janne Hyvï¿œinen 2002. All rights reserved.
+ *
+ *  Principles:
+ *
+ *
+ *  History:
+ *    2002-06     created
+ *    2002-08-12  added translation method 5 to addtag()
+ *                Tags taken from source file can't overwrite already existing items
+ *                added Init_Tags()
+ *    2002-08-13  Added all windows code pages
+ *    2002-10-09  Added code to parse tags from filename
+ *
+ *  Global functions:
+ *    - addtag()
+ *
+ *  TODO:
+ *    - '/' and '\' should be possible as PATH_SEP
+ */
+
+#include "mppenc.h"
+
+#ifdef USE_WIDECHAR
+# include <wchar.h>
+#endif
+
+
+static const char*  GenreList [] = {
+    "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge",
+    "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B",
+    "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska",
+    "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient",
+    "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical",
+    "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise",
+    "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative",
+    "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave",
+    "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream",
+    "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap",
+    "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave",
+    "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal",
+    "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll",
+    "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing", "Fast-Fusion",
+    "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde",
+    "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock",
+    "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour",
+    "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony",
+    "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club",
+    "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul",
+    "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A capella", "Euro-House",
+    "Dance Hall", "Goa", "Drum & Bass", "Club House", "Hardcore", "Terror",
+    "Indie", "BritPop", "NegerPunk", "Polsk Punk", "Beat", "Christian Gangsta",
+    "Heavy Metal", "Black Metal", "Crossover", "Contemporary C",
+    "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop",
+    "SynthPop"
+};
+
+
+struct APETagFooterStruct {
+    Uint8_t   ID       [8];    // should equal 'APETAGEX'
+    Uint8_t   Version  [4];    // currently 1000 (version 1.000)
+    Uint8_t   Length   [4];    // the complete size of the tag, including this footer
+    Uint8_t   TagCount [4];    // the number of fields in the tag
+    Uint8_t   Flags    [4];    // the tag flags (none currently defined)
+    Uint8_t   Reserved [8];    // reserved for later use
+};
+
+
+typedef struct {
+    char*           key;
+    size_t          keylen;
+    unsigned char*  value;
+    size_t          valuelen;
+    unsigned int    flags;
+} TagItem_t;
+
+
+static TagItem_t       T [256];                        // up to 256 items, otherwise program crashs
+static unsigned int    TagCount = 0;
+
+#if defined __TURBOC__
+
+static unsigned short  CP_850 [256] = {
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
+    0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
+    0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+    0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
+    0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+    0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
+    0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
+    0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0,
+};
+
+#elif defined _WIN32
+
+static unsigned short  CP_37 [256] = {  // ???
+    0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F, 0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
+    0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
+    0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5, 0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C,
+    0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF, 0x00EC, 0x00DF, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x00AC,
+    0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5, 0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
+    0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
+    0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
+    0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
+    0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
+    0x005E, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC, 0x00BD, 0x00BE, 0x005B, 0x005D, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
+    0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
+    0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
+    0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
+};
+
+static unsigned short  CP_42 [256] = { // CP_SYMBOLS
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0xF020, 0xF021, 0xF022, 0xF023, 0xF024, 0xF025, 0xF026, 0xF027, 0xF028, 0xF029, 0xF02A, 0xF02B, 0xF02C, 0xF02D, 0xF02E, 0xF02F,
+    0xF030, 0xF031, 0xF032, 0xF033, 0xF034, 0xF035, 0xF036, 0xF037, 0xF038, 0xF039, 0xF03A, 0xF03B, 0xF03C, 0xF03D, 0xF03E, 0xF03F,
+    0xF040, 0xF041, 0xF042, 0xF043, 0xF044, 0xF045, 0xF046, 0xF047, 0xF048, 0xF049, 0xF04A, 0xF04B, 0xF04C, 0xF04D, 0xF04E, 0xF04F,
+    0xF050, 0xF051, 0xF052, 0xF053, 0xF054, 0xF055, 0xF056, 0xF057, 0xF058, 0xF059, 0xF05A, 0xF05B, 0xF05C, 0xF05D, 0xF05E, 0xF05F,
+    0xF060, 0xF061, 0xF062, 0xF063, 0xF064, 0xF065, 0xF066, 0xF067, 0xF068, 0xF069, 0xF06A, 0xF06B, 0xF06C, 0xF06D, 0xF06E, 0xF06F,
+    0xF070, 0xF071, 0xF072, 0xF073, 0xF074, 0xF075, 0xF076, 0xF077, 0xF078, 0xF079, 0xF07A, 0xF07B, 0xF07C, 0xF07D, 0xF07E, 0xF07F,
+    0xF080, 0xF081, 0xF082, 0xF083, 0xF084, 0xF085, 0xF086, 0xF087, 0xF088, 0xF089, 0xF08A, 0xF08B, 0xF08C, 0xF08D, 0xF08E, 0xF08F,
+    0xF090, 0xF091, 0xF092, 0xF093, 0xF094, 0xF095, 0xF096, 0xF097, 0xF098, 0xF099, 0xF09A, 0xF09B, 0xF09C, 0xF09D, 0xF09E, 0xF09F,
+    0xF0A0, 0xF0A1, 0xF0A2, 0xF0A3, 0xF0A4, 0xF0A5, 0xF0A6, 0xF0A7, 0xF0A8, 0xF0A9, 0xF0AA, 0xF0AB, 0xF0AC, 0xF0AD, 0xF0AE, 0xF0AF,
+    0xF0B0, 0xF0B1, 0xF0B2, 0xF0B3, 0xF0B4, 0xF0B5, 0xF0B6, 0xF0B7, 0xF0B8, 0xF0B9, 0xF0BA, 0xF0BB, 0xF0BC, 0xF0BD, 0xF0BE, 0xF0BF,
+    0xF0C0, 0xF0C1, 0xF0C2, 0xF0C3, 0xF0C4, 0xF0C5, 0xF0C6, 0xF0C7, 0xF0C8, 0xF0C9, 0xF0CA, 0xF0CB, 0xF0CC, 0xF0CD, 0xF0CE, 0xF0CF,
+    0xF0D0, 0xF0D1, 0xF0D2, 0xF0D3, 0xF0D4, 0xF0D5, 0xF0D6, 0xF0D7, 0xF0D8, 0xF0D9, 0xF0DA, 0xF0DB, 0xF0DC, 0xF0DD, 0xF0DE, 0xF0DF,
+    0xF0E0, 0xF0E1, 0xF0E2, 0xF0E3, 0xF0E4, 0xF0E5, 0xF0E6, 0xF0E7, 0xF0E8, 0xF0E9, 0xF0EA, 0xF0EB, 0xF0EC, 0xF0ED, 0xF0EE, 0xF0EF,
+    0xF0F0, 0xF0F1, 0xF0F2, 0xF0F3, 0xF0F4, 0xF0F5, 0xF0F6, 0xF0F7, 0xF0F8, 0xF0F9, 0xF0FA, 0xF0FB, 0xF0FC, 0xF0FD, 0xF0FE, 0xF0FF,
+};
+
+static unsigned short  CP_437 [256] = { // MS-DOS: US
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
+    0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
+    0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+    0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+    0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+    0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+    0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
+    0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0,
+};
+
+static unsigned short  CP_500 [256] = { // ???
+    0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F, 0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087, 0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
+    0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004, 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
+    0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5, 0x00E7, 0x00F1, 0x005B, 0x002E, 0x003C, 0x0028, 0x002B, 0x0021,
+    0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF, 0x00EC, 0x00DF, 0x005D, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E,
+    0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5, 0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
+    0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
+    0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
+    0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
+    0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x00DD, 0x00DE, 0x00AE,
+    0x00A2, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC, 0x00BD, 0x00BE, 0x00AC, 0x007C, 0x00AF, 0x00A8, 0x00B4, 0x00D7,
+    0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
+    0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
+    0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
+};
+
+static unsigned short  CP_850 [256] = { // MS-DOS Latin 1
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
+    0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
+    0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+    0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
+    0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+    0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
+    0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
+    0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0,
+};
+
+static unsigned short  CP_860 [256] = { // MS-DOS: Portuguese
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2,
+    0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3,
+    0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+    0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+    0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+    0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+    0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
+    0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0,
+};
+
+static unsigned short  CP_861 [256] = { // MS-DOS: Iceland
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5,
+    0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
+    0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+    0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+    0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+    0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+    0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
+    0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0,
+};
+
+static unsigned short  CP_863 [256] = { // MS-DOS: Canadian French
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x2017, 0x00C0, 0x00A7,
+    0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192,
+    0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00B8, 0x00B3, 0x00AF, 0x00CE, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB,
+    0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+    0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+    0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+    0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
+    0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0,
+};
+
+static unsigned short  CP_865 [256] = { // MS-DOS: Nordic
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
+    0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192,
+    0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4,
+    0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+    0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+    0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+    0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
+    0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0,
+};
+
+static unsigned short  CP_874 [256] = { // MS-DOS: Thai
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x20AC, 0x0081, 0x0082, 0x0083, 0x0084, 0x2026, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+    0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+    0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
+    0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17, 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
+    0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
+    0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, 0x0E38, 0x0E39, 0x0E3A, 0xF8C1, 0xF8C2, 0xF8C3, 0xF8C4, 0x0E3F,
+    0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
+    0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xF8C5, 0xF8C6, 0xF8C7, 0xF8C8,
+};
+
+static unsigned short  CP_1250 [256] = { // Windows: Latin 2
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x20AC, 0x0081, 0x201A, 0x0083, 0x201E, 0x2026, 0x2020, 0x2021, 0x0088, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
+    0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0098, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
+    0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
+    0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
+    0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
+    0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
+    0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
+    0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9,
+};
+
+static unsigned short  CP_1251 [256] = { // Windows: Cyrillic
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
+    0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0098, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
+    0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7, 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
+    0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7, 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
+    0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+    0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
+    0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+    0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+};
+
+static unsigned short  CP_1252 [256] = { // Windows: Latin 1
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008D, 0x017D, 0x008F,
+    0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x009D, 0x017E, 0x0178,
+    0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+    0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+    0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+    0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+    0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+    0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF,
+};
+
+static unsigned short  CP_1253 [256] = { // Windows: Greek
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x0088, 0x2030, 0x008A, 0x2039, 0x008C, 0x008D, 0x008E, 0x008F,
+    0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0098, 0x2122, 0x009A, 0x203A, 0x009C, 0x009D, 0x009E, 0x009F,
+    0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0xF8F9, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
+    0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7, 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
+    0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+    0x03A0, 0x03A1, 0xF8FA, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
+    0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+    0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0xF8FB,
+};
+
+static unsigned short  CP_1254 [256] = { // Windows: Latin 5
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008D, 0x008E, 0x008F,
+    0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x009D, 0x009E, 0x0178,
+    0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+    0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+    0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+    0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF,
+    0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+    0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF,
+};
+
+static unsigned short  CP_1255 [256] = { // Windows: Hebrew
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x008A, 0x2039, 0x008C, 0x008D, 0x008E, 0x008F,
+    0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x009A, 0x203A, 0x009C, 0x009D, 0x009E, 0x009F,
+    0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AA, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+    0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+    0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7, 0x05B8, 0x05B9, 0x05BA, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
+    0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0xF88D, 0xF88E, 0xF88F, 0xF890, 0xF891, 0xF892, 0xF893,
+    0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+    0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0xF894, 0xF895, 0x200E, 0x200F, 0xF896,
+};
+
+static unsigned short  CP_1256 [256] = { // Windows: Arabic
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
+    0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
+    0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+    0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
+    0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
+    0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7, 0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643,
+    0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
+    0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7, 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2,
+};
+
+static unsigned short  CP_1257 [256] = { // Windows: Baltic
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x20AC, 0x0081, 0x201A, 0x0083, 0x201E, 0x2026, 0x2020, 0x2021, 0x0088, 0x2030, 0x008A, 0x2039, 0x008C, 0x00A8, 0x02C7, 0x00B8,
+    0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0098, 0x2122, 0x009A, 0x203A, 0x009C, 0x00AF, 0x02DB, 0x009F,
+    0x00A0, 0xF8FC, 0x00A2, 0x00A3, 0x00A4, 0xF8FD, 0x00A6, 0x00A7, 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6,
+    0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
+    0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
+    0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
+    0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
+    0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9,
+};
+
+static unsigned short  CP_1258 [256] = { // Windows: Vietnam
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x008A, 0x2039, 0x0152, 0x008D, 0x008E, 0x008F,
+    0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x009A, 0x203A, 0x0153, 0x009D, 0x009E, 0x0178,
+    0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+    0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+    0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
+    0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
+    0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
+    0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF,
+};
+
+static unsigned short  CP_10000 [256] = { // Apple Macintosh
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8,
+    0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC,
+    0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8,
+    0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x2126, 0x00E6, 0x00F8,
+    0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153,
+    0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, 0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02,
+    0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4,
+    0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7,
+};
+
+static unsigned short  CP_10079 [256] = { // ???
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+    0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
+    0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+    0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+    0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+    0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+    0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
+    0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8,
+    0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC,
+    0x00DD, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8,
+    0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x2126, 0x00E6, 0x00F8,
+    0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153,
+    0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, 0x00FF, 0x0178, 0x2044, 0x00A4, 0x00D0, 0x00F0, 0x00DE, 0x00FE,
+    0x00FD, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4,
+    0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7,
+};
+
+#endif
+
+
+/*
+ *  Resets Item Counter
+ *  Do frees any memory.
+ */
+
+void
+Init_Tags ( void )
+{
+    int  i;
+
+    for ( i = 0; i < (int)TagCount; i++ ) {
+        if ( T[i].key != NULL )
+            free ( T[i].key   );
+        T[i].key = NULL;
+        if ( T[i].value != NULL )
+            free ( T[i].value );
+        T[i].value = NULL;
+    }
+    TagCount = 0;
+}
+
+
+int
+gettag ( const char* key, char* dst, size_t len )
+{
+    size_t  valuelen;
+    size_t  keylen = strlen (key);
+    int     i;
+
+    for ( i = 0; i < (int)TagCount; i++ )
+        if ( keylen == T[i].keylen &&  0 == memcmp (T[i].key, key, keylen) ) {
+            valuelen = len-1 > T[i].valuelen  ?  T[i].valuelen  :  len-1 ;
+            memcpy ( dst, T[i].value, valuelen );
+            dst [valuelen] = '\0';
+            return 0;
+        }
+
+    memset ( dst, 0, len );
+    return -1;
+}
+
+
+static unsigned char*
+utf8char ( unsigned char* dst, unsigned long value )
+{
+    if      ( value == '\r'  ||  value == 0xFFFE  ||  value == 0xFFFF ) {
+        ;
+    }
+    else if ( value < 0x80 ) {
+        *dst++ = value;
+    }
+    else if ( value < 0x800 ) {
+        *dst++ = 0xC0 + ((value >>  6) & 0x1F);
+        *dst++ = 0x80 + ((value >>  0) & 0x3F);
+    }
+    else if ( value < 0x10000 ) {
+        *dst++ = 0xE0 + ((value >> 12) & 0x0F);
+        *dst++ = 0x80 + ((value >>  6) & 0x3F);
+        *dst++ = 0x80 + ((value >>  0) & 0x3F);
+    }
+    else if ( value < 0x200000 ) {
+        *dst++ = 0xF0 + ((value >> 18) & 0x07);
+        *dst++ = 0x80 + ((value >> 12) & 0x3F);
+        *dst++ = 0x80 + ((value >>  6) & 0x3F);
+        *dst++ = 0x80 + ((value >>  0) & 0x3F);
+    }
+    else if ( value < 0x4000000 ) {
+        *dst++ = 0xF8 + ((value >> 24) & 0x03);
+        *dst++ = 0x80 + ((value >> 18) & 0x3F);
+        *dst++ = 0x80 + ((value >> 12) & 0x3F);
+        *dst++ = 0x80 + ((value >>  6) & 0x3F);
+        *dst++ = 0x80 + ((value >>  0) & 0x3F);
+    }
+    else if ( value < 0x80000000 ) {
+        *dst++ = 0xFC + ((value >> 30) & 0x01);
+        *dst++ = 0x80 + ((value >> 24) & 0x3F);
+        *dst++ = 0x80 + ((value >> 18) & 0x3F);
+        *dst++ = 0x80 + ((value >> 12) & 0x3F);
+        *dst++ = 0x80 + ((value >>  6) & 0x3F);
+        *dst++ = 0x80 + ((value >>  0) & 0x3F);
+    }
+
+    return dst;
+}
+
+
+/*
+ *  IsUnicode()
+ *
+ *  Gets a memory block and tries to find out whether this is binary data or a valid Windows Unicode file.
+ *  When return 1, it is very likely (but not 100% secure) that the content is Unicode encoded.
+ */
+
+static int
+IsUnicode ( const char* src, size_t len )
+{
+    if ( len <= 2 )
+        return 0;
+
+    if ( len & 1 )                                              // odd number of bytes?
+        return 0;
+
+	if ( src [0] != 0xFFi  ||  src [1] != 0xFEi )                 // Microsoft Unicode preample (also useful to detect endianess, but currently only little endian is supported)
+        return 0;
+
+    for ( len >>= 1; len > 0; len--, src += 2 ) {               // Check for invalid codes (FFFE, FFFF, DC00...DFFF without a prepend D800...DBFF, D800...DBFF without a n appended DC00...DFFF)
+        if ( ( src [1] & 0xFC ) == 0xDC )
+            return 0;
+        if ( src [1] == 0xFFi  &&  ( src [0] & 0xFE ) == 0xFE )
+            return 0;
+        if ( ( src [1] & 0xFC ) == 0xD8 ) {
+            if ( len < 2  ||  ( src [3] & 0xFC ) != 0xDC )
+                return 0;
+        }
+        else {
+            len--;
+            src += 2;
+        }
+    }
+
+    return 1;                                                   // good chance to be a UTF-8
+}
+
+/*
+ *  addtag()
+ *
+ *  Add a item to the item list of a tag. Item key is given by (key,keylen), item value by (value,valuelen).
+ *
+ *  The following value translation modes are possible:
+ *    0: no translation at all
+ *    1: translate from console charset to UTF-8 (currently ISO-8859-1 for non-Windows and non-DOS OS)
+ *    2: auto detect: contents is a valid Window Unicode File => translate to UTF-8, else no translation at all
+ *    3: like 1), but convert ';' to null character
+ *    4: UTF-16 LE => translate to UTF-8
+ *    5: translate from ISO-8859-1 to UTF-8
+ *    6: like 1), but convert from OEM codepage (Win32)
+ *  (should become an enum)
+ *
+ *  Note:
+ *    Windows 95/98/ME has no usable NLS support
+ *
+ */
+
+int
+addtag ( const char*           key,             // the item key
+         size_t                keylen,          // length of item key, or 0 for auto-determine
+         const char*           value,           // the item value
+         size_t                valuelen,        // the length of the item value (before any possible translation)
+         int                   converttoutf8,   // convert flags of item value
+         int                   flags )          // item flags proposal
+{
+    unsigned char*  p;
+    unsigned char*  q;
+    char   ch;
+    size_t          i;
+#ifdef _WIN32
+    const unsigned short*  CP_ptr;
+    unsigned int           Codepage;
+
+    if ( converttoutf8 == 6 ) {
+        Codepage      = GetOEMCP ();
+        converttoutf8 = 1;
+    }
+    else {
+        Codepage      = GetACP ();
+    }
+
+    switch ( Codepage ) {
+    case CP_ACP:        CP_ptr =  CP_1252; break;
+    case CP_OEMCP:      CP_ptr =   CP_850; break;
+    case CP_MACCP:      CP_ptr = CP_10000; break;
+    case CP_THREAD_ACP: CP_ptr =  CP_1252; break;
+    default:    CP_ptr =   CP_850; break;
+    case    37: CP_ptr =    CP_37; break;
+    case    42: CP_ptr =    CP_42; break;
+    case   437: CP_ptr =   CP_437; break;
+    case   500: CP_ptr =   CP_500; break;
+    case   850: CP_ptr =   CP_850; break;
+    case   860: CP_ptr =   CP_860; break;
+    case   861: CP_ptr =   CP_861; break;
+    case   863: CP_ptr =   CP_863; break;
+    case   865: CP_ptr =   CP_865; break;
+    case   874: CP_ptr =   CP_874; break;
+    case  1250: CP_ptr =  CP_1250; break;
+    case  1251: CP_ptr =  CP_1251; break;
+    case  1252: CP_ptr =  CP_1252; break;
+    case  1253: CP_ptr =  CP_1253; break;
+    case  1254: CP_ptr =  CP_1254; break;
+    case  1255: CP_ptr =  CP_1255; break;
+    case  1256: CP_ptr =  CP_1256; break;
+    case  1257: CP_ptr =  CP_1257; break;
+    case  1258: CP_ptr =  CP_1258; break;
+    case 10000: CP_ptr = CP_10000; break;
+    case 10079: CP_ptr = CP_10079; break;
+    }
+#endif
+
+
+    if ( converttoutf8 == 2  &&  IsUnicode ( value, valuelen ) ) {
+        converttoutf8 = 4;
+        value        += 2;                      // remove first two bytes (zero width space 0xFEFF)
+        valuelen      = ( valuelen - 2) >> 1;
+        flags        &= ~2;                     // reset binary flag (it's now text)
+    }
+
+    if ( keylen == 0 )
+        keylen = strlen ( key );
+
+    p = malloc ( keylen );
+    memcpy ( p, key, keylen );
+	T [TagCount] . key    = (char*) p;
+    T [TagCount] . keylen = keylen;
+
+    switch ( converttoutf8 ) {
+    default:
+        p = malloc ( 1 * valuelen );    // copy
+        break;
+    case 1:                             // at most 1 native character => 3 UTF bytes
+    case 4:                             // at 1 wide => 3, 2 wide => 4
+        p = malloc ( 3 * valuelen );
+        break;
+    }
+
+    q = p;
+
+    for ( i = 0; i < valuelen; i++ ) {
+        ch = value [i];
+        switch ( converttoutf8 ) {
+        default:                        // 0: no translation at all --or-- 2: auto detect: contents is a valid Window Unicode File => translate to UTF-8, else no translation at all
+            *q++ = ch;
+            break;
+
+        case 5:                         // 5: translate from ISO-8859-1 to UTF-8
+            q = utf8char ( q, ch );
+            break;
+
+        case 3:                         // 3: like 1), but convert ';' to null character
+            if ( ch == ';' )
+                ch = '\0';
+            /* fall through */
+
+        case 1:                         // 1: translate from console charset to UTF-8 (currently ISO-8859-1 for non-Windows and non-DOS OS)
+#if defined __TURBOC__
+            q = utf8char ( q, CP_850 [ch] );
+#elif defined _WIN32
+            // fprintf ( stderr, "%c  %02X  U+%04X\n", ch, ch, CP_ptr [ch] );
+            q = utf8char ( q, CP_ptr [ch] );
+#elif defined USE_WIDECHAR
+            {
+            int      ret;
+            wchar_t  wch = 0;
+            ret = mbtowc ( &wch, value + i, valuelen - i );
+            if ( ret > 0 )
+                q = utf8char ( q, wch ), i += ret - 1;
+            }
+#else
+            q = utf8char ( q, ch );
+#endif
+            break;
+
+        case 4:                         // 4: UTF-16 LE => translate to UTF-8
+            if ( (value [i+i+1] & 0xFC ) == 0xD8  &&  (value [i+i+3] & 0xFC ) == 0xDC ) {   // UTF-16 code (2x16 bit for Unicodes 0x010000...0x10FFFF)
+                q = utf8char ( q, ((value [i+i] + (value [i+i+1] << 8) - 0xD800) << 10) + (value [i+i+2] + (value [i+i+3] << 8) - 0xDC00) + 0x10000 );
+                i++;
+            }
+            else {
+                q = utf8char ( q, value [i+i] + (value [i+i+1] << 8) );
+            }
+            break;
+        }
+    }
+
+    p = realloc ( p, valuelen = q-p );
+
+    for ( i = 0; i < TagCount; i++ )
+        if ( T [i].keylen == T [TagCount].keylen  &&  0 == strncasecmp (T [i].key, T [TagCount].key, T [i].keylen ) ) {    // found old tag with the same name => replace
+            free ( T [TagCount].key   );
+            free ( T [i].value );
+            goto set;
+        }
+
+    i = TagCount++;
+set:
+    T [i] . value    = p;
+    T [i] . valuelen = valuelen;
+    T [i] . flags    = flags;
+    return 0;
+}
+
+
+static int Cdecl
+cmpfn2 ( const void* p1, const void* p2 )
+{
+    const TagItem_t*  q1 = (TagItem_t*) p1;
+    const TagItem_t*  q2 = (TagItem_t*) p2;
+
+    return q1 -> valuelen - q2 -> valuelen;
+}
+
+/*
+ *  Writes collect tag items and write it to a file.
+ *  Items are destroyed, so tags can only be written once.
+ */
+
+int
+FinalizeTags ( FILE* fp, unsigned int Version )
+{
+    static unsigned char  H [32] = "APETAGEX";
+    unsigned char         dw [8];
+    unsigned long         estimatedbytes =  32; // 32 byte footer + all items, these are the 32 bytes footer, the items are added later
+    unsigned long         writtenbytes   = -32; // actually writtenbytes-32, which should be equal to estimatedbytes (= footer + all items)
+    unsigned int          i;
+
+    if ( TagCount == 0 )
+        return 0;
+
+    qsort ( T, TagCount, sizeof (*T), cmpfn2 );
+
+    for ( i = 0; i < TagCount; i++ )
+        estimatedbytes += 9 + T[i] . keylen + T[i] . valuelen;
+
+    if ( estimatedbytes >= 8192 + 103 )
+        stderr_printf ( "\nTag is %.1f Kbyte long. This is longer than the maximum recommended 8 KByte.\n\a", estimatedbytes/1024. );
+
+    H [ 8] = Version >>  0;
+    H [ 9] = Version >>  8;
+    H [10] = Version >> 16;
+    H [11] = Version >> 24;
+    H [12] = estimatedbytes >>  0;
+    H [13] = estimatedbytes >>  8;
+    H [14] = estimatedbytes >> 16;
+    H [15] = estimatedbytes >> 24;
+    H [16] = TagCount >>  0;
+    H [17] = TagCount >>  8;
+    H [18] = TagCount >> 16;
+    H [19] = TagCount >> 24;
+
+    H [23] = 0x80 | 0x20;
+    writtenbytes += fwrite ( H, 1, 32, fp );
+
+    for ( i = 0; i < TagCount; i++ ) {
+        dw [0] = T [i] . valuelen >>  0;
+        dw [1] = T [i] . valuelen >>  8;
+        dw [2] = T [i] . valuelen >> 16;
+        dw [3] = T [i] . valuelen >> 24;
+        dw [4] = T [i] . flags >>  0;
+        dw [5] = T [i] . flags >>  8;
+        dw [6] = T [i] . flags >> 16;
+        dw [7] = T [i] . flags >> 24;
+        writtenbytes += fwrite ( dw        , 1, 8            , fp );
+        writtenbytes += fwrite ( T[i].key  , 1, T[i].keylen  , fp );
+        writtenbytes += fwrite ( ""        , 1, 1            , fp );
+        if ( T[i].valuelen > 0 )
+            writtenbytes += fwrite ( T[i].value, 1, T[i].valuelen, fp );
+    }
+
+    H [23] = 0x80;
+    writtenbytes += fwrite ( H, 1, 32, fp );
+
+    if ( estimatedbytes != writtenbytes )
+        stderr_printf ( "\nError writing APE tag.\n" );
+
+    TagCount = 0;
+    return 0;
+}
+
+
+static int
+TagKeyExists ( const char* key, size_t keylen )
+{
+    unsigned int  i;
+
+    if ( keylen == 0 )
+        keylen = strlen ( key );
+
+    for ( i = 0; i < TagCount; i++ )
+        if ( T [i].keylen == keylen  &&  0 == strncasecmp (T [i].key, key, keylen ) )
+            return 1;
+
+    return 0;
+}
+
+
+/*
+ *  Copies src to dst. Copying is stopped at `\0' char is detected or if
+ *  len chars are copied.
+ *  Trailing blanks are removed and the string is `\0` terminated.
+ */
+
+static void
+memcpy_crop ( const char* key, char* src, size_t len, int flags )
+{
+    while ( len > 0  &&  ( src [len-1] == ' '  ||  src [len-1] == '\0' ) )
+        len--;
+
+    if ( len > 0 )
+        if ( ! TagKeyExists ( key, 0 ) )
+            addtag ( key, 0, src, len, 1, flags );
+}
+
+
+static int
+CopyTags_ID3 ( FILE* fp )
+{
+    Uint8_t  tmp [128];
+
+    if ( -1 == SEEK ( fp, -128L, SEEK_END ) )
+        return -1;
+
+    if ( 128 != READ ( fp, tmp, 128 ) )
+        return -1;
+
+    if ( 0 != memcmp ( tmp, "TAG", 3 ) ) {
+        return -1;
+    }
+
+    if ( !tmp[3]  &&  !tmp[33]  &&  !tmp[63]  &&  !tmp[93]  &&  !tmp[97] )
+        return -1;
+
+	memcpy_crop  ( "Title"  , (char*)tmp +  3, 30, 0 );
+	memcpy_crop  ( "Artist" , (char*)tmp + 33, 30, 0 );
+	memcpy_crop  ( "Album"  , (char*)tmp + 63, 30, 0 );
+	memcpy_crop  ( "Year"   , (char*)tmp + 93,  4, 0 );
+	memcpy_crop  ( "Comment", (char*)tmp + 97, 30, 0 );
+
+    if ( tmp[127] < sizeof(GenreList)/sizeof(*GenreList) )
+        if ( ! TagKeyExists ( "Genre", 0 ) )
+            addtag ("Genre", 0, GenreList [tmp[127]], strlen (GenreList [tmp[127]]), 0, 0 );
+
+    if ( tmp[125] == 0  &&  tmp[126] != 0 )
+        if ( ! TagKeyExists ( "Track", 0 ) ) {
+		sprintf ( (char*)tmp, "%u",  tmp[126] );
+		addtag ("Track", 0, (char*)tmp, strlen ((char*)tmp), 0, 0 );
+        }
+
+    return 0;
+}
+
+
+static unsigned int
+Read_LE_Uint32 ( const unsigned char* p )
+{
+    return ((Uint32_t)p[0] <<  0) |
+           ((Uint32_t)p[1] <<  8) |
+           ((Uint32_t)p[2] << 16) |
+           ((Uint32_t)p[3] << 24);
+}
+
+
+static int
+CopyTags_APE ( FILE* fp )
+{
+    Uint32_t                   len;
+    Uint32_t                   flags;
+    Uint32_t                   version;
+    unsigned char              buff [32768];
+    unsigned char              key [257];
+    unsigned char*             p;
+    struct APETagFooterStruct  T;
+    Uint32_t                   TagLen;
+    Uint32_t                   TagCount;
+    // Uint32_t                   tmp;
+
+    if ( -1 == SEEK ( fp, -(long)sizeof T, SEEK_END ) )
+        return -1;
+    if ( sizeof(T) != READ ( fp, &T, sizeof T ) )
+        return -1;
+    if ( memcmp ( T.ID, "APETAGEX", sizeof(T.ID) ) != 0 )
+        return -1;
+    version = Read_LE_Uint32 (T.Version);
+    if ( version != 1000  &&  version != 2000 )
+        return -1;
+    TagLen = Read_LE_Uint32 (T.Length);
+    if ( TagLen <= sizeof T )
+        return -1;
+    if ( -1 == SEEK ( fp, -(long)TagLen, SEEK_END ) )
+        return -1;
+    memset ( buff, 0, sizeof(buff) );
+    if ( TagLen - sizeof T != READ ( fp, buff, TagLen - sizeof T ) )
+        return -1;
+
+    TagCount = Read_LE_Uint32 (T.TagCount);
+    for ( p = buff; TagCount--; ) {
+        len   = Read_LE_Uint32 ( p );        p += 4;
+        flags = Read_LE_Uint32 ( p );        p += 4;
+		strcpy ( (char*)key, (char*)p );                   p += strlen ((char*)key) + 1;
+		if ( ! TagKeyExists ( (char*)key, 0 ) )
+			addtag ( (char*)key, 0, (char*)p, len > 0  &&  p [len-1] == '\0'  ?  len-1  :  len, version >= 2000  ?  0  :  5, flags );
+                                             p += len;
+    }
+
+    return 0;
+}
+
+static void
+FullPathName ( char* dst, size_t dstlen, const char* filename )         // Can contain stuff like ".." and "."
+{
+    // const char*  p;
+    char*        q     = dst;
+
+#if DRIVE_SEP != '\0'
+    int          drive = 0;
+
+    if ( isalpha (filename[0])  &&  filename[1] == DRIVE_SEP  &&  filename[2] != PATH_SEP ) {
+        drive     = filename[0] & 0x1F;
+        filename += 2;
+    }
+#endif
+
+    if ( filename[0] != PATH_SEP ) {
+#ifdef _WIN32
+        _getdcwd( drive, dst, dstlen );
+#else
+        getcwd ( dst, dstlen );
+#endif
+        q += strlen (q);
+#ifdef _WIN32
+        if ( dst[0] != PATH_SEP  ||  dst[1] != '\0' )
+#else
+        if ( dst[2] != PATH_SEP  ||  dst[3] != '\0' )
+#endif
+            *q++ = PATH_SEP;
+    }
+
+    strcpy ( q, filename );
+    return;
+}
+
+/********************************************************************************************/
+
+/*
+
+" "                             ' '
+" - "                           '-'
+"."                             '.'
+"/"                             '/'
+" -- "                          '_'
+"[#0]"                          '0'
+"[#n]"  [number]                'n'
+"#n"    number                  'M'
+"(#N)"  (CD x)                  'N'             it should also be possible: (CD x/x), (DVD x), (DVD x/x)
+"#A"    Artist                  'A'
+"#C"    CD/Album                'C'
+"#T"    Title                   'T'
+"#x"    extention               'x'
+
+
+/#C -- [#n] #A -- #T#x      | Acid Jazz/100% Acid Jazz -- [04] Leena Conquest (and Hip Hop Fingers) -- Boundaries (Radio Edit).pac
+/#C -- [#n] #A -- #C -- #T#x| Meditation/Jade Collection (1998) -- [10] Rhian -- Red Sun, Blue River -- The Miracle Song.mpc
+/#A/#C -- [#n] #T#x         | Andreas Vollenweider/Eolian Minstrel -- [02] Across the Iron River.pac
+/#A/#C#N -- [#n] #T#x       | Barbra Streisand/The Concert (CD 1) -- [01] Overture
+/#A -- #C -- [#n] #T#x      | Friedemann/Friedemann -- Aquamarin -- [09] In the Court of the Mermaid.pac
+/#C/[#n] #A -- #T#x         | Jazz Lyrik Prosa/[11] Eberhard Esche -- Anektode.pac
+/#A -- #T#x                 | Lais/Lais -- 06.pac
+/#C/(#N) -- [#n] #A -- #T#x | Tanz- und Folkfest 2001 -- Klingende Post/(CD 2) -- [09] Andy Irvine -- Gladiators.pac
+/#A -- #C -- [#0]#x         | Friedemann/Friedemann -- Aquamarin -- [00].pac
+/#A/#C (#N) -- [#0]#x       | Tangerine Dream/The Warsaw Concert (CD 2) -- [00].pac
+/#A/#T#x                    | Heinz-Rudolf Kunze/Dein ist mein ganzes Herz.pac
+/#A/#C -- [#0]#x            | Sting/Nada como el Sol -- [00].mpc
+
+*/
+
+static const char* const  parser_strings [] = {
+    "/A_Tx",
+    "/A/Tx",
+    "/A_C_0x",
+    "/C_n A_Tx",
+    "/C_n A_C_Tx",              // new
+    "/A/C_n Tx",
+    "/A/C N_n Tx",
+    "/A_C_n Tx",
+    "/C/n A_Tx",
+    "/C/N_n A_Tx",
+    "/A/C N_0x",
+    "/A/C_0x",
+};
+
+
+static void
+copy ( char* dst, const char* src, size_t len )
+{
+    memcpy ( dst, src, len );
+    dst [len] = '\0';
+}
+
+/*
+ *    dst[0] = Artist
+ *    dst[1] = CD
+ *    dst[2] = Title
+ *    dst[3] = +CD
+ *    dst[4] = number
+ *    dst[5] = ext
+ */
+
+#ifndef isdigit
+# define isdigit(x)         ((unsigned int)((x) - '0') < 10)
+#endif
+
+static int
+parse ( char** dst, const char* src, const char* format )
+{
+    int          i;
+    const char*  srcend = src + strlen(src);
+    const char*  p;
+    char*        q;
+
+    for ( i = 0; i < 6; i++)
+        dst[i][0] = '\0';
+
+    for ( i = strlen(format); i-- > 0; ) {
+        p = srcend;
+#ifndef STFU
+        stderr_printf ( "%c: ", format[i] );
+#endif
+        switch ( format[i] ) {
+        case '.':
+        case ' ':
+        case '/':                               // !!!!!!!
+            if (p[-1] != format[i])
+                return 1;
+            p--;
+            break;
+        case '_':
+            if (0 != memcmp (p-4, " -- ", 4))
+                return 1;
+            p -= 4;
+            break;
+        case '-':
+            if (0 != memcmp (p-3, " - ", 3))
+                return 1;
+            p -= 3;
+            break;
+        case '0':
+            if (p[-1] != ']' || p[-2] != '0' || p[-3] != '0' || p[-4] != '[')
+                return 1;
+            copy (dst[4], p-3, 2);
+            p -= 4;
+            break;
+        case 'n':
+            if (p[-1] != ']' || !isdigit(p[-2]) || !isdigit(p[-3]) || p[-4] != '[')
+                return 1;
+            copy (dst[4], p-3, 2);
+            p -= 4;
+            break;
+        case 'M':
+            if ( !isdigit(p[-1]) || !isdigit(p[-2]) )
+                return 1;
+            copy (dst[4], p-2, 2);
+            p -= 2;
+            break;
+        case 'N':
+            if (p[-1] != ')' || !isdigit(p[-2]) || p[-3] != ' ' || p[-4] != 'D' || p[-5] != 'C' || p[-6] != '(')
+                return 1;
+            dst[3][0] = ' ';
+            copy (dst[3]+1, p-6, 6);
+            p -= 6;
+            break;
+        case 'A':
+            q = dst[0]; goto big;
+        case 'C':
+            q = dst[1]; goto big;
+        case 'T':
+            q = dst[2]; goto big;
+        big:
+            while ( 0 == memcmp (p-4, "/mpc", 4)  ||
+                    0 == memcmp (p-4, "/mp3", 4)  ||
+                    0 == memcmp (p-4, "/pac", 4)  ||
+                    0 == memcmp (p-4, "/ape", 4)  ||
+                    0 == memcmp (p-4, "/pac", 4)  ||
+                    0 == memcmp (p-3, "/.." , 3)  ||
+                    0 == memcmp (p-2, "/."  , 2)
+                  ) {
+                      do {
+                          p--;
+                          srcend--;
+                      } while ( *p != PATH_SEP );
+                }
+            while ( p[-1] != PATH_SEP  &&
+                    p[-1] != DRIVE_SEP &&
+                    0 != memcmp (p-4, " -- ", 4 )  &&
+                    (p[-1] != ')' || !isdigit(p[-2]) || p[-3] != ' ' || p[-4] != 'D' || p[-5] != 'C' || p[-6] != '(')  &&
+                    (p[-1] != ' ' || p[-2] != ']' || !isdigit(p[-3]) || !isdigit(p[-4]) || p[-5] != '[') &&
+                    (p[-1] != ']' || p[-2] != '0' || p[-3] != '0' || p[-4] != '[')
+                  )
+                p--;
+            copy ( q, p, srcend - p );
+            break;
+        case 'x':
+            do {
+                p--;
+                if (p[0] == PATH_SEP || p[0] == DRIVE_SEP)
+                    return -1;
+            } while (*p != '.');
+            copy (dst[5], p, srcend-p );
+            break;
+        }
+#ifndef STFU
+        stderr_printf ( "%*.*s\033[7m%*.*s\033[0m\n", p-src, p-src, src, srcend-p, srcend-p, p );
+#endif
+        srcend = p;
+    }
+    return 0;
+}
+
+static int
+hexdigit ( const char s )
+{
+    if ( (unsigned char)(s-'0') < 10u )
+        return s-'0';
+    if ( (unsigned char)(s-'A') <  6u )
+        return s-'A'+10;
+    return -1;
+}
+
+static void
+spaceconverting ( char* dst, const char* src )          // can work inplace
+{
+    for ( ; src[0] != '\0' ; src++) {
+        if      ( src[0] == '_' )
+            *dst++ = ' ';
+        else if ( src[0] == '%'  &&  hexdigit(src[1]) >= 0  &&  hexdigit(src[2]) >= 0 )
+            *dst++ = hexdigit(src[1]) * 16 + hexdigit(src[2]), src += 2;
+        else
+            *dst++ = *src;
+    }
+    *dst = '\0';
+}
+
+
+static int
+Parser ( const char* src )
+{
+    size_t  i;
+    char    tmp  [6] [1024];
+    char*   buff [6] = { tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5] };
+    char    merge [1024];
+    char*   q;
+
+#ifndef STFU
+    stderr_printf ( "\n  %s\n", src );
+#endif
+
+    memset ( tmp  , 0, sizeof tmp   );
+    memset ( merge, 0, sizeof merge );
+
+    for ( i = 0; i < sizeof(parser_strings)/sizeof(*parser_strings); i++ ) {
+        if ( 0 == parse ( buff, src, parser_strings[i] ) ) {
+            sprintf ( merge, "%s%s", tmp[1], tmp[3] );
+            q = merge + strlen (merge);
+
+            if ( q-7 >= merge  &&  q[-7]==' '  &&  q[-6]=='('  && atoi(q-5) >= 1900  &&  atoi(q-5) < 2050  &&  q[-1] == ')' ) {
+                q[-1] = '\0';
+                q[-7] = '\0';
+                q -= 5;
+            }
+            else {
+                q = NULL;
+            }
+
+            spaceconverting ( tmp[0], tmp[0] );
+            spaceconverting ( merge , merge );
+            spaceconverting ( tmp[2], tmp[2] );
+            spaceconverting ( tmp[4], tmp[4] );
+            spaceconverting ( tmp[5], tmp[5] );
+
+            stderr_printf ("\n");
+            stderr_printf ("Artist = %s\n", tmp[0] );
+            stderr_printf ("CD     = %s\n", merge  );
+            stderr_printf ("Title  = %s\n", tmp[2] );
+            stderr_printf ("No#    = %s\n", tmp[4] );
+            stderr_printf ("Extent = %s\n", tmp[5] );
+            stderr_printf ("Year   = %s\n", q  ?  q  :  "????" );
+#if 1
+            if ( tmp[0][0]  &&  ! TagKeyExists ( "Artist", 0 ) ) addtag ( "Artist", 0, tmp[0], strlen (tmp[0]), 5, 0 );
+            if ( merge[0]   &&  ! TagKeyExists ( "Album" , 0 ) ) addtag ( "Album" , 0, merge , strlen (merge) , 5, 0 );
+            if ( tmp[2][0]  &&  ! TagKeyExists ( "Title" , 0 ) ) addtag ( "Title" , 0, tmp[2], strlen (tmp[2]), 5, 0 );
+            if ( tmp[4][0]  &&  ! TagKeyExists ( "Track" , 0 ) ) addtag ( "Track" , 0, tmp[4], strlen (tmp[4]), 5, 0 );
+            if ( q != NULL  &&  ! TagKeyExists ( "Year"  , 0 ) ) addtag ( "Year"  , 0, q     , 4              , 5, 0 );
+#endif
+            return 1;
+        }
+#ifndef STFU
+        stderr_printf ("???\n--\n");
+#endif
+    }
+
+    return 0;
+}
+
+
+/*******************************************************************************/
+
+
+static int
+CopyTags_Name ( const char* filename )
+{
+    char         buff [4096];
+
+    FullPathName  ( buff, sizeof buff, filename );
+    Parser        ( buff );
+    return 0;
+}
+
+
+int
+CopyTags ( const char* filename )
+{
+    FILE*  fp;
+
+    if ( 0 == strncmp (filename, "/dev/", 5 ) )
+        return 0;
+
+    fp = fopen ( filename, "rb" );
+    if ( fp == NULL )
+        return -1;
+
+    CopyTags_APE  (fp);                 // APE tags have higher priority than ID3V1 tags
+    CopyTags_ID3  (fp);
+    CopyTags_Name (filename);
+
+    fclose (fp);
+    return 0;
+}
+
+/* end of tags.c */
Index: /libmpc/branches/r2d/mppenc/wave_in.c
===================================================================
--- /libmpc/branches/r2d/mppenc/wave_in.c	(revision 133)
+++ /libmpc/branches/r2d/mppenc/wave_in.c	(revision 133)
@@ -0,0 +1,656 @@
+/*
+ * Musepack audio compression
+ * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf
+ *
+ * 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
+ */
+
+#include "mppenc.h"
+
+#ifdef _WIN32
+
+static int
+init_in ( const int  SampleCount,
+          const int  SampleFreq,
+          const int  Channels,
+          const int  BitsPerSample );
+static size_t
+get_in ( void* DataPtr );
+
+#endif
+
+
+#if defined USE_OSS_AUDIO  ||  defined USE_ESD_AUDIO  ||  defined USE_SUN_AUDIO
+static void
+Set_Realtime ( void )
+{
+# if defined USE_NICE
+    seteuid     ( 0 );
+    setpriority ( PRIO_PROCESS, getpid(), -20 );
+    seteuid     ( getuid() );
+# endif
+}
+#endif /* USE_OSS_AUDIO || USE_ESD_AUDIO || USE_SUN_AUDIO */
+
+
+#define EXT(x)  (0 == strcasecmp (ext, #x))
+
+int
+Open_WAV_Header ( wave_t* type, const char* filename )
+{
+    const char*  ext = strrchr ( filename, '.');
+    FILE*        fp;
+
+    type -> raw = 0;
+
+    if ( 0 == strcmp ( filename, "-")  ||  0 == strcmp ( filename, "/dev/stdin") ) {
+        fp = SETBINARY_IN ( stdin );
+    }
+#ifndef _WIN32
+#ifndef NO_DEV_AUDIO
+    else if ( 0 == strncmp ( filename, "/dev/", 5) ) {
+        int          fd;
+        int          arg;
+        int          org;
+
+        fd = open (filename, O_RDONLY);
+        if ( fd < 0 )
+            return -1;
+
+        type->Channels = org = arg = 2;
+        if ( -1 == ioctl ( fd, SOUND_PCM_WRITE_CHANNELS, &arg ) )
+            return -1;
+        if (arg != org)
+            return -1;
+
+        type->BitsPerSample = org = arg = 16;
+        type->BytesPerSample = 2;
+        if ( -1 == ioctl ( fd, SOUND_PCM_WRITE_BITS, &arg ) )
+            return -1;
+        if (arg != org)
+            return -1;
+
+        org = arg = AFMT_S16_LE;
+        if ( -1 == ioctl ( fd, SNDCTL_DSP_SETFMT, &arg ) )
+            return -1;
+        if ((arg & org) == 0)
+            return -1;
+
+        type->SampleFreq = org = arg = 44100.;
+        if ( -1 == ioctl ( fd, SOUND_PCM_WRITE_RATE, &arg ) )
+            return -1;
+        if ( 23.609375 * abs(arg-org) > abs(arg+org) )    // Sample frequency: Accept 40.5...48.0 kHz for 44.1 kHz
+            return -1;
+
+        type->raw        = 1;
+        type->PCMOffset  = 0;
+        type->PCMBytes   = 0xFFFFFFFF;
+        type->PCMSamples = 86400 * type->SampleFreq;
+
+        fp = fdopen (fd, "rb");
+        Set_Realtime ();
+    }
+#endif
+#else
+    else if ( 0 == strncmp ( filename, "/dev/audio", 10 ) ) {
+        int     tmp;
+        int     fs  = 44100;
+        double  dur = 86400.;
+
+        sscanf ( filename, "%*[^:]:%u:%lf", &fs, &dur );
+
+        fp                     = (FILE*)-1;
+        type -> Channels       =  2;
+        type -> BitsPerSample  = 16;
+        type -> BytesPerSample =  2;
+        type -> SampleFreq     = fs;
+        type -> PCMOffset      =  0;
+        type -> PCMBytes       = 0xFFFFFFFF;
+        type -> PCMSamples     = dur * type -> SampleFreq;
+        type -> raw            = 1;
+        tmp  = init_in ( 1152, (int) floor (type -> SampleFreq + 0.5), type -> Channels, type -> BitsPerSample );
+        if ( tmp )
+            return -1;
+# if   defined USE_REALTIME
+        SetPriorityClass ( GetCurrentProcess (), REALTIME_PRIORITY_CLASS );
+# elif defined USE_NICE
+        SetPriorityClass ( GetCurrentProcess (), HIGH_PRIORITY_CLASS );
+# endif
+    }
+#endif
+    else if ( ext == NULL ) {
+        fp = NULL;
+    }
+    else if ( EXT(.wav) ) {
+        fp = fopen ( filename, "rb" );
+    }
+    else if ( EXT(.wv) ) {                              // wavpack (www.wavpack.com)
+        fp = pipeopen ( "wvunpack # -", filename );
+    }
+    else if ( EXT(.la) ) {                              // lossless-audio (www.lossless-audio.com)
+        fp = pipeopen ( "la -console #", filename );
+    }
+    else if ( EXT(.raw)  ||  EXT(.cdr)  ||  EXT(.pcm) ) {
+        fp = fopen ( filename, "rb" );
+        type->Channels       = 2;
+        type->BitsPerSample  = 16;
+        type->BytesPerSample = 2;
+        type->SampleFreq     = 44100.;
+        type->raw            = 1;
+        type->PCMOffset      = 0;
+        type->PCMBytes       = 0xFFFFFFFF;
+        type->PCMSamples     = 86400 * type->SampleFreq;
+    }
+    else if ( EXT(.pac)  ||  EXT(.lpac)  ||  EXT(.lpa) ) {
+        fp = pipeopen ( "lpac -o -x #", filename );
+    }
+    else if ( EXT(.fla)  ||  EXT(.flac) ) {
+#ifdef _WIN32
+        stderr_printf ( "*** Install at least version 1.03 of FLAC.EXE. Thanks! ***\n\n" );
+#endif
+        fp = pipeopen ( "flac -d -s -c - < #", filename );
+    }
+    else if ( EXT(.rka)  ||  EXT(.rkau) ) {
+        fp = pipeopen ( "rkau # -", filename );
+    }
+    else if ( EXT(.sz) ) {
+        fp = pipeopen ( "szip -d < #", filename );
+    }
+    else if ( EXT(.sz2) ) {
+        fp = pipeopen ( "szip2 -d < #", filename );
+    }
+    else if ( EXT(.ofr) ) {
+        fp = pipeopen ( "optimfrog d # -", filename );
+    }
+    else if ( EXT(.ape) ) {
+        fp = pipeopen ( "mac # - -d", filename );
+    }
+    else if ( EXT(.shn)  ||  EXT(.shorten) ) {
+#ifdef _WIN32
+        stderr_printf ( "*** Install at least version 3.4 of Shorten.exe. Thanks! ***\n\n" );
+#endif
+        fp = pipeopen ( "shorten -x # -", filename );           // Test if it's okay !!!!
+        if ( fp == NULL )
+            fp = pipeopen ( "shortn32 -x # -", filename );
+    }
+    else if ( EXT(.mod) ) {
+        fp = pipeopen ( "xmp -b16 -c -f44100 --stereo -o- #", filename );
+        type->Channels       = 2;
+        type->BitsPerSample  = 16;
+        type->BytesPerSample = 2;
+        type->SampleFreq     = 44100.;
+        type->raw            = 1;
+        type->PCMOffset      = 0;
+        type->PCMBytes       = 0xFFFFFFFF;
+        type->PCMSamples     = 86400 * type->SampleFreq;
+    }
+    else {
+        fp = NULL;
+    }
+
+    type -> fp  = fp;
+    return fp == NULL  ?  -1  :  0;
+}
+
+#undef EXT
+
+
+static float f0  ( const void* p )
+{
+    return (void)p, 0.;
+}
+
+static float f8  ( const void* p )
+{
+    return (((unsigned char*)p)[0] - 128) * 256.;
+}
+
+static float f16 ( const void* p )
+{
+    return ((unsigned char*)p)[0] + 256. * ((signed char*)p)[1];
+}
+
+static float f24 ( const void* p )
+{
+    return ((unsigned char*)p)[0]*(1./256) + ((unsigned char*)p)[1] + 256 * ((signed char*)p)[2];
+}
+
+static float f32 ( const void* p )
+{
+    return ((unsigned char*)p)[0]*(1./65536) + ((unsigned char*)p)[1]*(1./256) + ((unsigned char*)p)[2] + 256 * ((signed char*)p)[3];
+}
+
+
+typedef float (*rf_t) (const void*);
+
+static int
+DigitalSilence ( void* buffer, size_t len )
+{
+    unsigned long*  pl;
+    unsigned char*  pc;
+    size_t          loops;
+
+    for ( pl = buffer, loops = len >> 3; loops--; pl += 2 )
+        if ( pl[0] | pl[1] )
+            return 0;
+
+    for ( pc = (unsigned char*)pl, loops = len & 7; loops--; pc++ )
+        if ( pc[0] )
+            return 0;
+
+    return 1;
+}
+
+
+size_t
+Read_WAV_Samples ( wave_t*          t,
+                   const size_t     RequestedSamples,
+                   PCMDataTyp*      data,
+                   const ptrdiff_t  offset,
+                   const float      scalel,
+                   const float      scaler,
+                   int*             Silence )
+{
+    static const rf_t rf [5] = { f0, f8, f16, f24, f32 };
+    short   Buffer [8 * 32/16 * BLOCK]; // read buffer, up to 8 channels, up to 32 bit
+    size_t  ReadSamples;                // returns number of read samples
+    size_t  i;
+    short*  b = (short*) Buffer;
+    char*   c = (char*) Buffer;
+    float*  l = data -> L + offset;
+    float*  r = data -> R + offset;
+    float*  m = data -> M + offset;
+    float*  s = data -> S + offset;
+
+    // Read PCM data
+#ifdef _WIN32
+    if ( t->fp != (FILE*)-1 ) {
+        ReadSamples = fread ( b, t->BytesPerSample * t->Channels, RequestedSamples, t->fp );
+    }
+    else {
+        while (1) {
+            ReadSamples = get_in (b) / ( t->Channels * t->BytesPerSample );
+            if ( ReadSamples != 0 )
+                break;
+            Sleep (10);
+        }
+    }
+#else
+    ReadSamples = fread ( b, t->BytesPerSample * t->Channels, RequestedSamples, t->fp );
+#endif
+
+
+    *Silence    = DigitalSilence ( b, ReadSamples * t->BytesPerSample * t->Channels );
+
+    // Add Null Samples if EOF is reached
+    if ( ReadSamples != RequestedSamples )
+        //memset ( b + ReadSamples * t->Channels, 0, (RequestedSamples - ReadSamples) * (sizeof(short) * t->Channels) );
+		memset ( c + ReadSamples * t->Channels * t->BytesPerSample, t->BytesPerSample == 1 ? 0x80 : 0, (RequestedSamples - ReadSamples) * (t->BytesPerSample * t->Channels) );
+
+    // Convert to float and calculate M=(L+R)/2 and S=(L-R)/2 signals
+#if ENDIAN == HAVE_LITTLE_ENDIAN
+    if ( t->BytesPerSample == 2 ) {
+        switch ( t->Channels ) {
+        case 1:
+            for ( i = 0; i < RequestedSamples; i++, b++ ) {
+				float temp = b[0] * scalel;
+				l[i] = temp + MPPENC_DENORMAL_FIX_LEFT;
+				r[i] = temp + MPPENC_DENORMAL_FIX_RIGHT;
+                m[i] = (l[i] + r[i]) * 0.5f;
+                s[i] = (l[i] - r[i]) * 0.5f;
+            }
+            break;
+        case 2:
+            for ( i = 0; i < RequestedSamples; i++, b += 2 ) {
+                l[i] = b[0] * scalel + MPPENC_DENORMAL_FIX_LEFT;           // left
+                r[i] = b[1] * scaler + MPPENC_DENORMAL_FIX_RIGHT;           // right
+                m[i] = (l[i] + r[i]) * 0.5f;
+                s[i] = (l[i] - r[i]) * 0.5f;
+            }
+            break;
+        case 5:
+        case 6:
+        case 7:
+        case 8:
+            for ( i = 0; i < RequestedSamples; i++, b += t->Channels ) {
+                l[i] = (0.4142 * b[0] + 0.2928 * b[1] + 0.2928 * b[3] - 0.1464 * b[4]) * scalel + MPPENC_DENORMAL_FIX_LEFT;           // left
+                r[i] = (0.4142 * b[2] + 0.2928 * b[1] + 0.2928 * b[4] - 0.1464 * b[3]) * scaler + MPPENC_DENORMAL_FIX_RIGHT;           // right
+                m[i] = (l[i] + r[i]) * 0.5f;
+                s[i] = (l[i] - r[i]) * 0.5f;
+            }
+            break;
+        default:
+            for ( i = 0; i < RequestedSamples; i++, b += t->Channels ) {
+                l[i] = b[0] * scalel + MPPENC_DENORMAL_FIX_LEFT;           // left
+                r[i] = b[1] * scaler + MPPENC_DENORMAL_FIX_RIGHT;           // right
+                m[i] = (l[i] + r[i]) * 0.5f;
+                s[i] = (l[i] - r[i]) * 0.5f;
+            }
+            break;
+        }
+    }
+    else
+#endif
+         {
+        unsigned int  bytes = t->BytesPerSample;
+        rf_t          f     = rf [bytes];
+
+        c = (char*)b;
+        switch ( t->Channels ) {
+        case 1:
+            for ( i = 0; i < RequestedSamples; i++, c += bytes ) {
+				float temp = f(c) * scalel;
+				l[i] = temp + MPPENC_DENORMAL_FIX_LEFT;
+				r[i] = temp + MPPENC_DENORMAL_FIX_RIGHT;
+                m[i] = (l[i] + r[i]) * 0.5f;
+                s[i] = (l[i] - r[i]) * 0.5f;
+            }
+            break;
+        case 2:
+            for ( i = 0; i < RequestedSamples; i++, c += 2*bytes ) {
+                l[i] = f(c)       * scalel + MPPENC_DENORMAL_FIX_LEFT;     // left
+                r[i] = f(c+bytes) * scaler + MPPENC_DENORMAL_FIX_RIGHT;     // right
+                m[i] = (l[i] + r[i]) * 0.5f;
+                s[i] = (l[i] - r[i]) * 0.5f;
+            }
+            break;
+        default:
+            for ( i = 0; i < RequestedSamples; i++, c += bytes * t->Channels ) {
+                l[i] = f(c)       * scalel + MPPENC_DENORMAL_FIX_LEFT;     // left
+                r[i] = f(c+bytes) * scaler + MPPENC_DENORMAL_FIX_RIGHT;     // right
+                m[i] = (l[i] + r[i]) * 0.5f;
+                s[i] = (l[i] - r[i]) * 0.5f;
+            }
+            break;
+        }
+    }
+    return ReadSamples;
+}
+
+
+// read WAVE header
+
+static unsigned short
+Read16 ( FILE* fp )
+{
+    unsigned char  buff [2];
+
+    if (fread ( buff, 1, 2, fp ) != 2 )
+        return -1;
+    return buff[0] | (buff[1] << 8);
+}
+
+static unsigned long
+Read32 ( FILE* fp )
+{
+    unsigned char  buff [4];
+
+    if ( fread ( buff, 1, 4, fp ) != 4 )
+        return -1;
+    return (buff[0] | (buff[1] << 8)) | ((unsigned long)(buff[2] | (buff[3] << 8)) << 16);
+}
+
+
+int
+Read_WAV_Header ( wave_t* type )
+{
+	int bytealign;
+
+    FILE*  fp = type->fp;
+
+    if ( type->raw )
+        return 0;
+
+    fseek ( fp, 0, SEEK_SET );
+    if ( Read32 (fp) != 0x46464952 ) {                  // 4 Byte: check for "RIFF"
+        stderr_printf ( Read32(fp) == -1  ?  " ERROR: Empty file or no data from coprocess!\n\n"
+                                          :  " ERROR: 'RIFF' not found in WAVE header!\n\n");
+        return -1;
+    }
+    Read32 (fp);                                        // 4 Byte: chunk size (ignored)
+    if ( Read32 (fp) != 0x45564157 ) {                  // 4 Byte: check for "WAVE"
+        stderr_printf ( " ERROR: 'WAVE' not found in WAVE header!\n\n");
+        return -1;
+    }
+    if ( Read32 (fp) != 0x20746D66 ) {                  // 4 Byte: check for "fmt "
+        stderr_printf ( " ERROR: 'fmt ' not found in WAVE header!\n\n");
+        return -1;
+    }
+    Read32 (fp);                                        // 4 Byte: read chunk-size (ignored)
+    if ( Read16 (fp) != 0x0001 ) {                      // 2 Byte: check for linear PCM
+        stderr_printf ( " ERROR: WAVE file has no linear PCM format!\n\n");
+        return -1;
+    }
+    type -> Channels    = Read16 (fp);                  // 2 Byte: read no. of channels
+    type -> SampleFreq  = Read32 (fp);                  // 4 Byte: read sampling frequency
+    Read32 (fp);                                        // 4 Byte: read avg. blocksize (fs*channels*bytepersample)
+    bytealign = Read16 (fp);							// 2 Byte: read byte-alignment (channels*bytepersample)
+    type->BitsPerSample = Read16 (fp);                  // 2 Byte: read bits per sample
+    type->BytesPerSample= (type->BitsPerSample + 7) / 8;
+    while ( 1 ) {                                       // search for "data"
+        if ( feof (fp) )
+            return -1;
+        if ( Read16 (fp) != 0x6164 )
+            continue;
+        if ( Read16 (fp) == 0x6174 )
+            break;
+    }
+    type->PCMBytes      = Read32 (fp);                  // 4 Byte: no. of byte in file
+    if ( feof (fp) ) return -1;
+
+														// finally calculate number of samples
+    if (type->PCMBytes >= 0xFFFFFF00  ||
+			type->PCMBytes == 0  ||
+			(Uint32_t)type->PCMBytes % (type -> Channels * type->BytesPerSample) != 0) {
+		type->PCMSamples = 36000000 * type->SampleFreq;
+	}
+	else {
+		type->PCMSamples = type->PCMBytes / bytealign;
+	}
+    type->PCMOffset     = ftell (fp);
+    return 0;
+}
+
+
+#ifdef _WIN32
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <windows.h>
+#include <winbase.h>
+#include <mmsystem.h>
+#ifndef __MINGW32__
+#include <mmreg.h>
+#endif
+#include <io.h>
+#include <fcntl.h>
+
+
+#define NBLK  383               // 10 sec of audio
+
+
+typedef struct {
+    int      active;
+    char*    data;
+    size_t   datalen;
+    WAVEHDR  hdr;
+} oblk_t;
+
+static HWAVEIN       Input_WAVHandle;
+static HWAVEOUT      Output_WAVHandle;
+static size_t        BufferBytes;
+static WAVEHDR       whi    [NBLK];
+static char*         data   [NBLK];
+static oblk_t        array  [NBLK];
+static unsigned int  NextInputIndex;
+static unsigned int  NextOutputIndex;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+int
+init_in ( const int  SampleCount,
+          const int  SampleFreq,
+          const int  Channels,
+          const int  BitsPerSample )
+{
+
+    WAVEFORMATEX  pwf;
+    MMRESULT      r;
+    int           i;
+
+    pwf.wFormatTag      = WAVE_FORMAT_PCM;
+    pwf.nChannels       = Channels;
+    pwf.nSamplesPerSec  = SampleFreq;
+    pwf.nAvgBytesPerSec = SampleFreq * Channels * ((BitsPerSample + 7) / 8);
+    pwf.nBlockAlign     = Channels * ((BitsPerSample + 7) / 8);
+    pwf.wBitsPerSample  = BitsPerSample;
+    pwf.cbSize          = 0;
+
+    r = waveInOpen ( &Input_WAVHandle, WAVE_MAPPER, &pwf, 0, 0, CALLBACK_EVENT );
+    if ( r != MMSYSERR_NOERROR ) {
+        fprintf ( stderr, "waveInOpen failed: ");
+        switch (r) {
+        case MMSYSERR_ALLOCATED:   fprintf ( stderr, "resource already allocated\n" );                                  break;
+        case MMSYSERR_INVALPARAM:  fprintf ( stderr, "invalid Params\n" );                                              break;
+        case MMSYSERR_BADDEVICEID: fprintf ( stderr, "device identifier out of range\n" );                              break;
+        case MMSYSERR_NODRIVER:    fprintf ( stderr, "no device driver present\n" );                                    break;
+        case MMSYSERR_NOMEM:       fprintf ( stderr, "unable to allocate or lock memory\n" );                           break;
+        case WAVERR_BADFORMAT:     fprintf ( stderr, "attempted to open with an unsupported waveform-audio format\n" ); break;
+        case WAVERR_SYNC:          fprintf ( stderr, "device is synchronous but waveOutOpen was\n" );                   break;
+        default:                   fprintf ( stderr, "unknown error code: %#X\n", r );                                  break;
+        }
+        return -1;
+    }
+
+    BufferBytes = SampleCount * Channels * ((BitsPerSample + 7) / 8);
+
+    for ( i = 0; i < NBLK; i++ ) {
+        whi [i].lpData         = data [i] = malloc (BufferBytes);
+        whi [i].dwBufferLength = BufferBytes;
+        whi [i].dwFlags        = 0;
+        whi [i].dwLoops        = 0;
+
+        r = waveInPrepareHeader ( Input_WAVHandle, whi + i, sizeof (*whi) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveInPrepareHeader  (%u) failed\n", i );  return -1; }
+        r = waveInAddBuffer     ( Input_WAVHandle, whi + i, sizeof (*whi) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveInAddBuffer      (%u) failed\n", i );  return -1; }
+    }
+    NextInputIndex = 0;
+    waveInStart (Input_WAVHandle);
+    return 0;
+}
+
+
+size_t
+get_in ( void* DataPtr )
+{
+    MMRESULT  r;
+    size_t    Bytes;
+
+    if ( whi [NextInputIndex].dwFlags & WHDR_DONE ) {
+        Bytes = whi [NextInputIndex].dwBytesRecorded;
+        memcpy ( DataPtr, data [NextInputIndex], Bytes );
+
+        r = waveInUnprepareHeader ( Input_WAVHandle, whi + NextInputIndex, sizeof (*whi) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveInUnprepareHeader (%d) failed\n", NextInputIndex ); return -1; }
+        whi [NextInputIndex].lpData         = data [NextInputIndex];
+        whi [NextInputIndex].dwBufferLength = BufferBytes;
+        whi [NextInputIndex].dwFlags        = 0;
+        whi [NextInputIndex].dwLoops        = 0;
+        r = waveInPrepareHeader   ( Input_WAVHandle, whi + NextInputIndex, sizeof (*whi) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveInPrepareHeader   (%d) failed\n", NextInputIndex ); return -1; }
+        r = waveInAddBuffer       ( Input_WAVHandle, whi + NextInputIndex, sizeof (*whi) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveInAddBuffer       (%d) failed\n", NextInputIndex ); return -1; }
+        NextInputIndex = (NextInputIndex + 1) % NBLK;
+        return  Bytes;
+    }
+    return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+int
+init_out ( const int  SampleCount,
+           const int  SampleFreq,
+           const int  Channels,
+           const int  BitsPerSample )
+{
+    WAVEFORMATEX  pwf;
+    MMRESULT      r;
+    int           i;
+
+    pwf.wFormatTag      = WAVE_FORMAT_PCM;
+    pwf.nChannels       = Channels;
+    pwf.nSamplesPerSec  = SampleFreq;
+    pwf.nAvgBytesPerSec = SampleFreq * Channels * ((BitsPerSample + 7) / 8);
+    pwf.nBlockAlign     = Channels * ((BitsPerSample + 7) / 8);
+    pwf.wBitsPerSample  = BitsPerSample;
+    pwf.cbSize          = 0;
+
+    r = waveOutOpen ( &Output_WAVHandle, WAVE_MAPPER, &pwf, 0, 0, CALLBACK_EVENT );
+    if ( r != MMSYSERR_NOERROR ) {
+        fprintf ( stderr, "waveOutOpen failed\n" );
+        switch (r) {
+        case MMSYSERR_ALLOCATED:   fprintf ( stderr, "resource already allocated\n" );                                  break;
+        case MMSYSERR_INVALPARAM:  fprintf ( stderr, "invalid Params\n" );                                              break;
+        case MMSYSERR_BADDEVICEID: fprintf ( stderr, "device identifier out of range\n" );                              break;
+        case MMSYSERR_NODRIVER:    fprintf ( stderr, "no device driver present\n" );                                    break;
+        case MMSYSERR_NOMEM:       fprintf ( stderr, "unable to allocate or lock memory\n" );                           break;
+        case WAVERR_BADFORMAT:     fprintf ( stderr, "attempted to open with an unsupported waveform-audio format\n" ); break;
+        case WAVERR_SYNC:          fprintf ( stderr, "device is synchronous but waveOutOpen was\n" );                   break;
+        default:                   fprintf ( stderr, "unknown error code: %#X\n", r );                                  break;
+        }
+        return -1;
+    }
+
+    BufferBytes = SampleCount * Channels * ((BitsPerSample + 7) / 8);
+
+    for ( i = 0; i < NBLK; i++ ) {
+        array [i].active = 0;
+        array [i].data   = malloc (BufferBytes);
+    }
+    NextOutputIndex = 0;
+    return 0;
+}
+
+
+int
+put_out ( const void*   DataPtr,
+          const size_t  Bytes )
+{
+    MMRESULT  r;
+    int       i = NextOutputIndex;
+
+    if ( array [i].active )
+        while ( ! (array [i].hdr.dwFlags & WHDR_DONE) )
+            Sleep (26);
+
+    r = waveOutUnprepareHeader ( Output_WAVHandle, &(array [i].hdr), sizeof (array [i].hdr) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveOutUnprepareHeader (%d) failed\n", i ); return -1; }
+
+    array [i].active             = 1;
+    array [i].hdr.lpData         = array [i].data;
+    array [i].hdr.dwBufferLength = Bytes;
+    array [i].hdr.dwFlags        = 0;
+    array [i].hdr.dwLoops        = 0;
+    memcpy ( array [i].data, DataPtr, Bytes );
+
+    r = waveOutPrepareHeader   ( Output_WAVHandle, &(array [i].hdr), sizeof (array [i].hdr) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveOutPrepareHeader   (%d) failed\n", i ); return -1; }
+    r = waveOutWrite           ( Output_WAVHandle, &(array [i].hdr), sizeof (array [i].hdr) ); if ( r != MMSYSERR_NOERROR ) { fprintf ( stderr, "waveOutAddBuffer       (%d) failed\n", i ); return -1; }
+
+    NextInputIndex = (NextInputIndex + 1) % NBLK;
+    return Bytes;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
+/* end of wave_in.c */
Index: /libmpc/branches/r2d/mppenc/winmsg.c
===================================================================
--- /libmpc/branches/r2d/mppenc/winmsg.c	(revision 133)
+++ /libmpc/branches/r2d/mppenc/winmsg.c	(revision 133)
@@ -0,0 +1,90 @@
+/*
+ * Musepack audio compression
+ * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf
+ *
+ * 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
+ */
+
+#include "mppenc.h"
+
+#ifdef _WIN32
+
+#include <windows.h>
+
+static HWND  FrontEndHandle;
+
+
+int
+SearchForFrontend ( void )
+{
+    FrontEndHandle = FindWindow ( NULL, "mpcdispatcher" );      // check for dispatcher window and (send startup-message???)
+
+    return FrontEndHandle != 0;
+}
+
+
+static void
+SendMsg ( const char* s )
+{
+    COPYDATASTRUCT  MsgData;
+
+    MsgData.dwData = 3;         // build message
+    MsgData.lpData = (char*)s;
+    MsgData.cbData = strlen(s) + 1;
+
+    SendMessage ( FrontEndHandle, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &MsgData );  // send message
+}
+
+
+void
+SendStartupMessage ( const char*  Version,
+                     const int    SV)
+{
+    char  startup [120];
+
+    sprintf ( startup, "#START#MP+ v%s SV%i", Version, SV);   // fill startup-message
+    SendMsg ( startup );
+}
+
+
+void
+SendQuitMessage ( void )
+{
+    SendMsg ("#EOF#");
+}
+
+
+void
+SendModeMessage ( const int Profile )
+{
+    char  message [32];
+
+    sprintf ( message, "#PARAM#%d#", Profile-8 );  // fill message
+    SendMsg ( message );
+}
+
+
+void                                            /* sends progress information to the frontend */
+SendProgressMessage ( const int    bitrate,
+                      const float  speed,
+                      const float  percent )
+{
+    char  message [64];
+
+    sprintf ( message, "#STAT#%4ik %5.2fx %5.1f%%#", bitrate, speed, percent );
+    SendMsg ( message );
+}
+
+#endif /* _WIN32 */
