Browse Source

A new audio player model

louyihua 8 years ago
parent
commit
f0e7a2bfed
94 changed files with 65710 additions and 425 deletions
  1. 2 1
      Makefile
  2. 4 4
      battle.c
  3. 9 2
      common.h
  4. 7 7
      ending.c
  5. 1 1
      game.c
  6. 61 1
      global.c
  7. 23 0
      global.h
  8. 210 0
      liboggvorbis/include/ogg/ogg.h
  9. 147 0
      liboggvorbis/include/ogg/os_types.h
  10. 244 0
      liboggvorbis/include/vorbis/codec.h
  11. 436 0
      liboggvorbis/include/vorbis/vorbisenc.h
  12. 206 0
      liboggvorbis/include/vorbis/vorbisfile.h
  13. 120 0
      liboggvorbis/src/analysis.c
  14. 144 0
      liboggvorbis/src/backends.h
  15. 253 0
      liboggvorbis/src/bitrate.c
  16. 59 0
      liboggvorbis/src/bitrate.h
  17. 1088 0
      liboggvorbis/src/bitwise.c
  18. 1050 0
      liboggvorbis/src/block.c
  19. 12274 0
      liboggvorbis/src/books/coupled/res_books_51.h
  20. 15783 0
      liboggvorbis/src/books/coupled/res_books_stereo.h
  21. 1547 0
      liboggvorbis/src/books/floor/floor_books.h
  22. 7758 0
      liboggvorbis/src/books/uncoupled/res_books_uncoupled.h
  23. 484 0
      liboggvorbis/src/codebook.c
  24. 119 0
      liboggvorbis/src/codebook.h
  25. 167 0
      liboggvorbis/src/codec_internal.h
  26. 375 0
      liboggvorbis/src/envelope.c
  27. 80 0
      liboggvorbis/src/envelope.h
  28. 224 0
      liboggvorbis/src/floor0.c
  29. 1102 0
      liboggvorbis/src/floor1.c
  30. 2111 0
      liboggvorbis/src/framing.c
  31. 58 0
      liboggvorbis/src/highlevel.h
  32. 668 0
      liboggvorbis/src/info.c
  33. 94 0
      liboggvorbis/src/lookup.c
  34. 32 0
      liboggvorbis/src/lookup.h
  35. 192 0
      liboggvorbis/src/lookup_data.h
  36. 160 0
      liboggvorbis/src/lpc.c
  37. 29 0
      liboggvorbis/src/lpc.h
  38. 456 0
      liboggvorbis/src/lsp.c
  39. 28 0
      liboggvorbis/src/lsp.h
  40. 816 0
      liboggvorbis/src/mapping0.c
  41. 785 0
      liboggvorbis/src/masking.h
  42. 563 0
      liboggvorbis/src/mdct.c
  43. 71 0
      liboggvorbis/src/mdct.h
  44. 57 0
      liboggvorbis/src/misc.h
  45. 260 0
      liboggvorbis/src/modes/floor_all.h
  46. 51 0
      liboggvorbis/src/modes/psych_11.h
  47. 133 0
      liboggvorbis/src/modes/psych_16.h
  48. 642 0
      liboggvorbis/src/modes/psych_44.h
  49. 101 0
      liboggvorbis/src/modes/psych_8.h
  50. 163 0
      liboggvorbis/src/modes/residue_16.h
  51. 292 0
      liboggvorbis/src/modes/residue_44.h
  52. 451 0
      liboggvorbis/src/modes/residue_44p51.h
  53. 318 0
      liboggvorbis/src/modes/residue_44u.h
  54. 109 0
      liboggvorbis/src/modes/residue_8.h
  55. 143 0
      liboggvorbis/src/modes/setup_11.h
  56. 153 0
      liboggvorbis/src/modes/setup_16.h
  57. 128 0
      liboggvorbis/src/modes/setup_22.h
  58. 132 0
      liboggvorbis/src/modes/setup_32.h
  59. 117 0
      liboggvorbis/src/modes/setup_44.h
  60. 74 0
      liboggvorbis/src/modes/setup_44p51.h
  61. 74 0
      liboggvorbis/src/modes/setup_44u.h
  62. 149 0
      liboggvorbis/src/modes/setup_8.h
  63. 225 0
      liboggvorbis/src/modes/setup_X.h
  64. 190 0
      liboggvorbis/src/os.h
  65. 1206 0
      liboggvorbis/src/psy.c
  66. 154 0
      liboggvorbis/src/psy.h
  67. 45 0
      liboggvorbis/src/registry.c
  68. 32 0
      liboggvorbis/src/registry.h
  69. 899 0
      liboggvorbis/src/res0.c
  70. 90 0
      liboggvorbis/src/scales.h
  71. 579 0
      liboggvorbis/src/sharedbook.c
  72. 1255 0
      liboggvorbis/src/smallft.c
  73. 34 0
      liboggvorbis/src/smallft.h
  74. 184 0
      liboggvorbis/src/synthesis.c
  75. 1215 0
      liboggvorbis/src/vorbisenc.c
  76. 2341 0
      liboggvorbis/src/vorbisfile.c
  77. 2136 0
      liboggvorbis/src/window.c
  78. 26 0
      liboggvorbis/src/window.h
  79. 4 2
      main.c
  80. 1 1
      main.h
  81. 3 2
      midi.c
  82. 157 0
      mp3player.c
  83. 531 0
      oggplay.c
  84. 1 1
      play.c
  85. 28 14
      rixplay.h
  86. 245 227
      rixplay.cpp
  87. 3 3
      script.c
  88. 34 0
      sdlpal.cfg.example
  89. 76 3
      sdlpal.vcxproj
  90. 252 3
      sdlpal.vcxproj.filters
  91. 161 135
      sound.c
  92. 8 10
      sound.h
  93. 1 1
      text.c
  94. 7 7
      uigame.c

+ 2 - 1
Makefile

@@ -6,7 +6,8 @@ HOST =
 
 ADPLUG_FILES = adplug/rix.cpp adplug/player.cpp adplug/binio.cpp \
 	adplug/fprovide.cpp adplug/binfile.cpp adplug/dosbox_opl.cpp \
-	adplug/fmopl.c adplug/surroundopl.cpp adplug/emuopl.cpp
+	adplug/fmopl.c adplug/surroundopl.cpp adplug/emuopl.cpp \
+	adplug/demuopl.cpp
 
 LIBMAD_FILES = libmad/bit.c libmad/decoder.c libmad/fixed.c libmad/frame.c \
 	libmad/huffman.c libmad/layer12.c libmad/layer3.c libmad/music_mad.c \

+ 4 - 4
battle.c

@@ -331,7 +331,7 @@ PAL_BattleMain(
    //
    // Fade out the music and delay for a while
    //
-   PAL_PlayMUS(0, FALSE, 1);
+   SOUND_PlayMUS(0, FALSE, 1);
    UTIL_Delay(200);
 
    //
@@ -342,7 +342,7 @@ PAL_BattleMain(
    //
    // Play the battle music
    //
-   PAL_PlayMUS(gpGlobals->wNumBattleMusic, TRUE, 0);
+   SOUND_PlayMUS(gpGlobals->wNumBattleMusic, TRUE, 0);
 
    //
    // Fade in the screen when needed
@@ -656,7 +656,7 @@ PAL_BattleWon(
       //
       // Play the "battle win" music
       //
-      PAL_PlayMUS(g_Battle.fIsBoss ? 2 : 3, FALSE, 0);
+      SOUND_PlayMUS(g_Battle.fIsBoss ? 2 : 3, FALSE, 0);
 
       //
       // Show the message about the total number of exp. and cash gained
@@ -1469,7 +1469,7 @@ PAL_StartBattle(
 
    gpGlobals->fInBattle = FALSE;
 
-   PAL_PlayMUS(gpGlobals->wNumMusic, TRUE, 1);
+   SOUND_PlayMUS(gpGlobals->wNumMusic, TRUE, 1);
 
    //
    // Restore the screen waving effects

+ 9 - 2
common.h

@@ -30,6 +30,7 @@ extern "C"
 {
 #endif
 
+#include <wchar.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -134,12 +135,17 @@ FILE *MY_fopen(const char *path, const char *mode);
 #ifndef _WIN32_WCE
 #if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION <= 2
 #define PAL_ALLOW_KEYREPEAT   1
-#define PAL_HAS_CD            1
+#define PAL_HAS_SDLCD         1
+#else
+#define PAL_HAS_SDLCD         0
 #endif
 #if !defined (CYGWIN) && !defined (DINGOO) && !defined (GPH) && !defined (GEKKO) && !defined (__WINPHONE__)
 #define PAL_HAS_MP3           1
 #endif
 #endif
+#define PAL_HAS_OGG           1
+#define PAL_HAS_MAME          1   /* Should not be enabled for now, until M.A.M.E goes open source licenses */
+
 #ifndef PAL_PREFIX
 #define PAL_PREFIX            "./"
 #endif
@@ -161,7 +167,9 @@ FILE *MY_fopen(const char *path, const char *mode);
 #include <io.h>
 #endif
 
+#if defined(_MSC_VER) && _MSC_VER < 1900
 #define vsnprintf _vsnprintf
+#endif
 
 #ifdef _MSC_VER
 #pragma warning (disable:4244)
@@ -180,7 +188,6 @@ typedef const BYTE *LPCBYTE;
 #else
 
 #include <unistd.h>
-#include <wchar.h>
 
 #ifndef FALSE
 #define FALSE               0

+ 7 - 7
ending.c

@@ -434,13 +434,13 @@ PAL_EndingScreen(
    VOID
 )
 {
-	RIX_Play(0x1a, TRUE, 0);
+	SOUND_PlayMUS(0x1a, TRUE, 0);
 	PAL_RNGPlay(gpGlobals->iCurPlayingRNG, 110, 150, 7);
 	PAL_RNGPlay(gpGlobals->iCurPlayingRNG, 151, 999, 9);
 
 	PAL_FadeOut(2);
 
-	RIX_Play(0x19, TRUE, 0);
+	SOUND_PlayMUS(0x19, TRUE, 0);
 
 	PAL_ShowFBP(75, 0);
 	PAL_FadeIn(5, FALSE, 1);
@@ -453,12 +453,12 @@ PAL_EndingScreen(
 	gpGlobals->fNeedToFadeIn = TRUE;
 	PAL_EndingAnimation();
 
-	RIX_Play(0, FALSE, 2);
+	SOUND_PlayMUS(0, FALSE, 2);
 	PAL_ColorFade(7, 15, FALSE);
 
 	if (!SOUND_PlayCDA(2))
 	{
-		RIX_Play(0x11, TRUE, 0);
+		SOUND_PlayMUS(0x11, TRUE, 0);
 	}
 
 	SDL_FillRect(gpScreen, NULL, 0);
@@ -491,12 +491,12 @@ PAL_EndingScreen(
 	PAL_ShowFBP(68, 6);
 
 	PAL_WaitForKey(0);
-	RIX_Play(0, FALSE, 1);
+	SOUND_PlayMUS(0, FALSE, 1);
 	UTIL_Delay(500);
 
 	if (!SOUND_PlayCDA(13))
 	{
-		RIX_Play(9, TRUE, 0);
+		SOUND_PlayMUS(9, TRUE, 0);
 	}
 
 	PAL_ScrollFBP(67, 0xf, TRUE);
@@ -509,7 +509,7 @@ PAL_EndingScreen(
 	PAL_ScrollFBP(60, 0xf, TRUE);
 	PAL_ScrollFBP(59, 0xf, TRUE);
 
-	RIX_Play(0, FALSE, 6);
+	SOUND_PlayMUS(0, FALSE, 6);
 	PAL_FadeOut(3);
 }
 

+ 1 - 1
game.c

@@ -47,7 +47,7 @@ PAL_GameStart(
       //
       // Fade in music if the player has loaded an old game.
       //
-      PAL_PlayMUS(gpGlobals->wNumMusic, TRUE, 1);
+      SOUND_PlayMUS(gpGlobals->wNumMusic, TRUE, 1);
    }
 
    gpGlobals->fNeedToFadeIn = TRUE;

+ 61 - 1
global.c

@@ -24,6 +24,7 @@
 #include "main.h"
 
 LPGLOBALVARS gpGlobals = NULL;
+extern BOOL g_fUseMidi;
 
 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
 #define DO_BYTESWAP(buf, size)
@@ -66,11 +67,17 @@ PAL_InitGlobals(
 {
    FILE     *fp;
    CODEPAGE  iCodePage = CP_UNKNOWN;
-   DWORD     dwWordLength = 10;		// Default for PAL DOS/WIN95
+   DWORD     dwWordLength = 10;			// Default for PAL DOS/WIN95
    DWORD     dwExtraMagicDescLines = 0;	// Default for PAL DOS/WIN95
    DWORD     dwExtraItemDescLines = 0;	// Default for PAL DOS/WIN95
    DWORD     dwIsDOS = 1;				// Default for DOS
    DWORD     dwUseEmbeddedFonts = 1;	// Default for using embedded fonts in DOS version
+   DWORD     dwUseSurroundOPL = 1;		// Default for using surround opl
+   DWORD     dwUseStereo = 1;			// Default for stereo audio
+   INT       iSampleRate = 44100;		// Default for 44KHz
+   MUSICTYPE eMusicType = g_fUseMidi ? MUSIC_MIDI : MUSIC_RIX;
+   MUSICTYPE eCDType = PAL_HAS_SDLCD ? MUSIC_SDLCD : MUSIC_OGG;
+   OPLTYPE   eOPLType = OPL_DOSBOX;
 
    if (gpGlobals == NULL)
    {
@@ -137,6 +144,52 @@ PAL_InitGlobals(
 				   {
 					   sscanf(ptr, "%u", &dwUseEmbeddedFonts);
 				   }
+				   else if (SDL_strcasecmp(p, "USESURROUNDOPL") == 0)
+				   {
+					   sscanf(ptr, "%u", &dwUseSurroundOPL);
+				   }
+				   else if (SDL_strcasecmp(p, "STEREO") == 0)
+				   {
+					   sscanf(ptr, "%u", &dwUseStereo);
+				   }
+				   else if (SDL_strcasecmp(p, "SAMPLERATE") == 0)
+				   {
+					   sscanf(ptr, "%d", &iSampleRate);
+					   if (iSampleRate > PAL_MAX_SAMPLERATE) iSampleRate = PAL_MAX_SAMPLERATE;
+				   }
+				   else if (SDL_strcasecmp(p, "CD") == 0)
+				   {
+					   char cd_type[32];
+					   sscanf(ptr, "%31s", cd_type);
+					   if (PAL_HAS_MP3 && SDL_strcasecmp(cd_type, "MP3") == 0)
+						   eCDType = MUSIC_MP3;
+					   else if (PAL_HAS_OGG && SDL_strcasecmp(cd_type, "OGG") == 0)
+						   eCDType = MUSIC_OGG;
+					   else if (PAL_HAS_SDLCD && SDL_strcasecmp(cd_type, "RAW") == 0)
+						   eCDType = MUSIC_SDLCD;
+				   }
+				   else if (SDL_strcasecmp(p, "MUSIC") == 0)
+				   {
+					   char music_type[32];
+					   sscanf(ptr, "%31s", music_type);
+					   if (PAL_HAS_NATIVEMIDI && SDL_strcasecmp(music_type, "MIDI") == 0)
+						   eMusicType = MUSIC_MIDI;
+					   else if (PAL_HAS_MP3 && SDL_strcasecmp(music_type, "MP3") == 0)
+						   eMusicType = MUSIC_MP3;
+					   else if (PAL_HAS_OGG && SDL_strcasecmp(music_type, "OGG") == 0)
+						   eMusicType = MUSIC_OGG;
+					   else if (SDL_strcasecmp(music_type, "RIX") == 0)
+						   eMusicType = MUSIC_RIX;
+				   }
+				   else if (SDL_strcasecmp(p, "OPL") == 0)
+				   {
+					   char opl_type[32];
+					   sscanf(ptr, "%31s", opl_type);
+					   if (SDL_strcasecmp(opl_type, "DOSBOX") == 0)
+						   eOPLType = OPL_DOSBOX;
+					   else if (PAL_HAS_MAME && SDL_strcasecmp(opl_type, "MAME") == 0)
+						   eOPLType = OPL_MAME;
+				   }
 			   }
 		   }
 	   }
@@ -189,6 +242,13 @@ PAL_InitGlobals(
    // Choose version
    gpGlobals->fIsWIN95 = dwIsDOS ? FALSE : TRUE;
    gpGlobals->fUseEmbeddedFonts = dwIsDOS && dwUseEmbeddedFonts ? TRUE : FALSE;
+   gpGlobals->fUseSurroundOPL = dwUseStereo && dwUseSurroundOPL ? TRUE : FALSE;
+   gpGlobals->iAudioChannels = dwUseStereo ? 2 : 1;
+   gpGlobals->iSampleRate = iSampleRate;
+   gpGlobals->eMusicType = eMusicType;
+   gpGlobals->eCDType = eCDType;
+   gpGlobals->eOPLType = eOPLType;
+
    // Set decompress function
    Decompress = gpGlobals->fIsWIN95 ? YJ2_Decompress : YJ1_Decompress;
 

+ 23 - 0
global.h

@@ -25,6 +25,7 @@
 #define GLOBAL_H
 
 #include "common.h"
+#include "palcommon.h"
 #include "map.h"
 #include "ui.h"
 
@@ -542,6 +543,21 @@ typedef struct tagPOISONSTATUS
    WORD              wPoisonScript;   // script entry
 } POISONSTATUS, *LPPOISONSTATUS;
 
+typedef enum tagMUSICTYPE
+{
+	MUSIC_RIX,
+	MUSIC_MIDI,
+	MUSIC_MP3,
+	MUSIC_OGG,
+	MUSIC_SDLCD
+} MUSICTYPE, *LPMUSICTYPE;
+
+typedef enum tagOPLTYPE
+{
+	OPL_DOSBOX,
+	OPL_MAME
+} OPLTYPE, *LPOPLTYPE;
+
 typedef struct tagGLOBALVARS
 {
    FILES            f;
@@ -593,12 +609,19 @@ typedef struct tagGLOBALVARS
    LPOBJECTDESC     lpObjectDesc;
    DWORD            dwFrameNum;
 
+   /* Configurable options */
    CODEPAGE         iCodePage;
    DWORD            dwWordLength;
    DWORD            dwExtraMagicDescLines;
    DWORD            dwExtraItemDescLines;
+   INT              iAudioChannels;
+   INT              iSampleRate;
+   MUSICTYPE        eMusicType;
+   MUSICTYPE        eCDType;
+   OPLTYPE          eOPLType;
    BOOL             fIsWIN95;
    BOOL             fUseEmbeddedFonts;
+   BOOL             fUseSurroundOPL;
 } GLOBALVARS, *LPGLOBALVARS;
 
 extern LPGLOBALVARS gpGlobals;

+ 210 - 0
liboggvorbis/include/ogg/ogg.h

@@ -0,0 +1,210 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: toplevel libogg include
+ last mod: $Id: ogg.h 18044 2011-08-01 17:55:20Z gmaxwell $
+
+ ********************************************************************/
+#ifndef _OGG_H
+#define _OGG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <ogg/os_types.h>
+
+typedef struct {
+  void *iov_base;
+  size_t iov_len;
+} ogg_iovec_t;
+
+typedef struct {
+  long endbyte;
+  int  endbit;
+
+  unsigned char *buffer;
+  unsigned char *ptr;
+  long storage;
+} oggpack_buffer;
+
+/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
+
+typedef struct {
+  unsigned char *header;
+  long header_len;
+  unsigned char *body;
+  long body_len;
+} ogg_page;
+
+/* ogg_stream_state contains the current encode/decode state of a logical
+   Ogg bitstream **********************************************************/
+
+typedef struct {
+  unsigned char   *body_data;    /* bytes from packet bodies */
+  long    body_storage;          /* storage elements allocated */
+  long    body_fill;             /* elements stored; fill mark */
+  long    body_returned;         /* elements of fill returned */
+
+
+  int     *lacing_vals;      /* The values that will go to the segment table */
+  ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact
+                                this way, but it is simple coupled to the
+                                lacing fifo */
+  long    lacing_storage;
+  long    lacing_fill;
+  long    lacing_packet;
+  long    lacing_returned;
+
+  unsigned char    header[282];      /* working space for header encode */
+  int              header_fill;
+
+  int     e_o_s;          /* set when we have buffered the last packet in the
+                             logical bitstream */
+  int     b_o_s;          /* set after we've written the initial page
+                             of a logical bitstream */
+  long    serialno;
+  long    pageno;
+  ogg_int64_t  packetno;  /* sequence number for decode; the framing
+                             knows where there's a hole in the data,
+                             but we need coupling so that the codec
+                             (which is in a separate abstraction
+                             layer) also knows about the gap */
+  ogg_int64_t   granulepos;
+
+} ogg_stream_state;
+
+/* ogg_packet is used to encapsulate the data and metadata belonging
+   to a single raw Ogg/Vorbis packet *************************************/
+
+typedef struct {
+  unsigned char *packet;
+  long  bytes;
+  long  b_o_s;
+  long  e_o_s;
+
+  ogg_int64_t  granulepos;
+
+  ogg_int64_t  packetno;     /* sequence number for decode; the framing
+                                knows where there's a hole in the data,
+                                but we need coupling so that the codec
+                                (which is in a separate abstraction
+                                layer) also knows about the gap */
+} ogg_packet;
+
+typedef struct {
+  unsigned char *data;
+  int storage;
+  int fill;
+  int returned;
+
+  int unsynced;
+  int headerbytes;
+  int bodybytes;
+} ogg_sync_state;
+
+/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
+
+extern void  oggpack_writeinit(oggpack_buffer *b);
+extern int   oggpack_writecheck(oggpack_buffer *b);
+extern void  oggpack_writetrunc(oggpack_buffer *b,long bits);
+extern void  oggpack_writealign(oggpack_buffer *b);
+extern void  oggpack_writecopy(oggpack_buffer *b,void *source,long bits);
+extern void  oggpack_reset(oggpack_buffer *b);
+extern void  oggpack_writeclear(oggpack_buffer *b);
+extern void  oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
+extern void  oggpack_write(oggpack_buffer *b,unsigned long value,int bits);
+extern long  oggpack_look(oggpack_buffer *b,int bits);
+extern long  oggpack_look1(oggpack_buffer *b);
+extern void  oggpack_adv(oggpack_buffer *b,int bits);
+extern void  oggpack_adv1(oggpack_buffer *b);
+extern long  oggpack_read(oggpack_buffer *b,int bits);
+extern long  oggpack_read1(oggpack_buffer *b);
+extern long  oggpack_bytes(oggpack_buffer *b);
+extern long  oggpack_bits(oggpack_buffer *b);
+extern unsigned char *oggpack_get_buffer(oggpack_buffer *b);
+
+extern void  oggpackB_writeinit(oggpack_buffer *b);
+extern int   oggpackB_writecheck(oggpack_buffer *b);
+extern void  oggpackB_writetrunc(oggpack_buffer *b,long bits);
+extern void  oggpackB_writealign(oggpack_buffer *b);
+extern void  oggpackB_writecopy(oggpack_buffer *b,void *source,long bits);
+extern void  oggpackB_reset(oggpack_buffer *b);
+extern void  oggpackB_writeclear(oggpack_buffer *b);
+extern void  oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
+extern void  oggpackB_write(oggpack_buffer *b,unsigned long value,int bits);
+extern long  oggpackB_look(oggpack_buffer *b,int bits);
+extern long  oggpackB_look1(oggpack_buffer *b);
+extern void  oggpackB_adv(oggpack_buffer *b,int bits);
+extern void  oggpackB_adv1(oggpack_buffer *b);
+extern long  oggpackB_read(oggpack_buffer *b,int bits);
+extern long  oggpackB_read1(oggpack_buffer *b);
+extern long  oggpackB_bytes(oggpack_buffer *b);
+extern long  oggpackB_bits(oggpack_buffer *b);
+extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);
+
+/* Ogg BITSTREAM PRIMITIVES: encoding **************************/
+
+extern int      ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
+extern int      ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov,
+                                   int count, long e_o_s, ogg_int64_t granulepos);
+extern int      ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
+extern int      ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill);
+extern int      ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
+extern int      ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill);
+
+/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
+
+extern int      ogg_sync_init(ogg_sync_state *oy);
+extern int      ogg_sync_clear(ogg_sync_state *oy);
+extern int      ogg_sync_reset(ogg_sync_state *oy);
+extern int      ogg_sync_destroy(ogg_sync_state *oy);
+extern int      ogg_sync_check(ogg_sync_state *oy);
+
+extern char    *ogg_sync_buffer(ogg_sync_state *oy, long size);
+extern int      ogg_sync_wrote(ogg_sync_state *oy, long bytes);
+extern long     ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og);
+extern int      ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og);
+extern int      ogg_stream_pagein(ogg_stream_state *os, ogg_page *og);
+extern int      ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op);
+extern int      ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op);
+
+/* Ogg BITSTREAM PRIMITIVES: general ***************************/
+
+extern int      ogg_stream_init(ogg_stream_state *os,int serialno);
+extern int      ogg_stream_clear(ogg_stream_state *os);
+extern int      ogg_stream_reset(ogg_stream_state *os);
+extern int      ogg_stream_reset_serialno(ogg_stream_state *os,int serialno);
+extern int      ogg_stream_destroy(ogg_stream_state *os);
+extern int      ogg_stream_check(ogg_stream_state *os);
+extern int      ogg_stream_eos(ogg_stream_state *os);
+
+extern void     ogg_page_checksum_set(ogg_page *og);
+
+extern int      ogg_page_version(const ogg_page *og);
+extern int      ogg_page_continued(const ogg_page *og);
+extern int      ogg_page_bos(const ogg_page *og);
+extern int      ogg_page_eos(const ogg_page *og);
+extern ogg_int64_t  ogg_page_granulepos(const ogg_page *og);
+extern int      ogg_page_serialno(const ogg_page *og);
+extern long     ogg_page_pageno(const ogg_page *og);
+extern int      ogg_page_packets(const ogg_page *og);
+
+extern void     ogg_packet_clear(ogg_packet *op);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _OGG_H */

+ 147 - 0
liboggvorbis/include/ogg/os_types.h

@@ -0,0 +1,147 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: #ifdef jail to whip a few platforms into the UNIX ideal.
+ last mod: $Id: os_types.h 19098 2014-02-26 19:06:45Z giles $
+
+ ********************************************************************/
+#ifndef _OS_TYPES_H
+#define _OS_TYPES_H
+
+/* make it easy on the folks that want to compile the libs with a
+   different malloc than stdlib */
+#define _ogg_malloc  malloc
+#define _ogg_calloc  calloc
+#define _ogg_realloc realloc
+#define _ogg_free    free
+
+#if defined(_WIN32)
+
+#  if defined(__CYGWIN__)
+#    include <stdint.h>
+     typedef int16_t ogg_int16_t;
+     typedef uint16_t ogg_uint16_t;
+     typedef int32_t ogg_int32_t;
+     typedef uint32_t ogg_uint32_t;
+     typedef int64_t ogg_int64_t;
+     typedef uint64_t ogg_uint64_t;
+#  elif defined(__MINGW32__)
+#    include <sys/types.h>
+     typedef short ogg_int16_t;
+     typedef unsigned short ogg_uint16_t;
+     typedef int ogg_int32_t;
+     typedef unsigned int ogg_uint32_t;
+     typedef long long ogg_int64_t;
+     typedef unsigned long long ogg_uint64_t;
+#  elif defined(__MWERKS__)
+     typedef long long ogg_int64_t;
+     typedef int ogg_int32_t;
+     typedef unsigned int ogg_uint32_t;
+     typedef short ogg_int16_t;
+     typedef unsigned short ogg_uint16_t;
+#  else
+     /* MSVC/Borland */
+     typedef __int64 ogg_int64_t;
+     typedef __int32 ogg_int32_t;
+     typedef unsigned __int32 ogg_uint32_t;
+     typedef __int16 ogg_int16_t;
+     typedef unsigned __int16 ogg_uint16_t;
+#  endif
+
+#elif defined(__MACOS__)
+
+#  include <sys/types.h>
+   typedef SInt16 ogg_int16_t;
+   typedef UInt16 ogg_uint16_t;
+   typedef SInt32 ogg_int32_t;
+   typedef UInt32 ogg_uint32_t;
+   typedef SInt64 ogg_int64_t;
+
+#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
+
+#  include <inttypes.h>
+   typedef int16_t ogg_int16_t;
+   typedef uint16_t ogg_uint16_t;
+   typedef int32_t ogg_int32_t;
+   typedef uint32_t ogg_uint32_t;
+   typedef int64_t ogg_int64_t;
+
+#elif defined(__HAIKU__)
+
+  /* Haiku */
+#  include <sys/types.h>
+   typedef short ogg_int16_t;
+   typedef unsigned short ogg_uint16_t;
+   typedef int ogg_int32_t;
+   typedef unsigned int ogg_uint32_t;
+   typedef long long ogg_int64_t;
+
+#elif defined(__BEOS__)
+
+   /* Be */
+#  include <inttypes.h>
+   typedef int16_t ogg_int16_t;
+   typedef uint16_t ogg_uint16_t;
+   typedef int32_t ogg_int32_t;
+   typedef uint32_t ogg_uint32_t;
+   typedef int64_t ogg_int64_t;
+
+#elif defined (__EMX__)
+
+   /* OS/2 GCC */
+   typedef short ogg_int16_t;
+   typedef unsigned short ogg_uint16_t;
+   typedef int ogg_int32_t;
+   typedef unsigned int ogg_uint32_t;
+   typedef long long ogg_int64_t;
+
+#elif defined (DJGPP)
+
+   /* DJGPP */
+   typedef short ogg_int16_t;
+   typedef int ogg_int32_t;
+   typedef unsigned int ogg_uint32_t;
+   typedef long long ogg_int64_t;
+
+#elif defined(R5900)
+
+   /* PS2 EE */
+   typedef long ogg_int64_t;
+   typedef int ogg_int32_t;
+   typedef unsigned ogg_uint32_t;
+   typedef short ogg_int16_t;
+
+#elif defined(__SYMBIAN32__)
+
+   /* Symbian GCC */
+   typedef signed short ogg_int16_t;
+   typedef unsigned short ogg_uint16_t;
+   typedef signed int ogg_int32_t;
+   typedef unsigned int ogg_uint32_t;
+   typedef long long int ogg_int64_t;
+
+#elif defined(__TMS320C6X__)
+
+   /* TI C64x compiler */
+   typedef signed short ogg_int16_t;
+   typedef unsigned short ogg_uint16_t;
+   typedef signed int ogg_int32_t;
+   typedef unsigned int ogg_uint32_t;
+   typedef long long int ogg_int64_t;
+
+#else
+
+#  include <ogg/config_types.h>
+
+#endif
+
+#endif  /* _OS_TYPES_H */

+ 244 - 0
liboggvorbis/include/vorbis/codec.h

@@ -0,0 +1,244 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+
+ ********************************************************************
+
+ function: libvorbis codec headers
+ last mod: $Id: codec.h 17021 2010-03-24 09:29:41Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _vorbis_codec_h_
+#define _vorbis_codec_h_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#include <ogg/ogg.h>
+
+typedef struct vorbis_info{
+  int version;
+  int channels;
+  long rate;
+
+  /* The below bitrate declarations are *hints*.
+     Combinations of the three values carry the following implications:
+
+     all three set to the same value:
+       implies a fixed rate bitstream
+     only nominal set:
+       implies a VBR stream that averages the nominal bitrate.  No hard
+       upper/lower limit
+     upper and or lower set:
+       implies a VBR bitstream that obeys the bitrate limits. nominal
+       may also be set to give a nominal rate.
+     none set:
+       the coder does not care to speculate.
+  */
+
+  long bitrate_upper;
+  long bitrate_nominal;
+  long bitrate_lower;
+  long bitrate_window;
+
+  void *codec_setup;
+} vorbis_info;
+
+/* vorbis_dsp_state buffers the current vorbis audio
+   analysis/synthesis state.  The DSP state belongs to a specific
+   logical bitstream ****************************************************/
+typedef struct vorbis_dsp_state{
+  int analysisp;
+  vorbis_info *vi;
+
+  float **pcm;
+  float **pcmret;
+  int      pcm_storage;
+  int      pcm_current;
+  int      pcm_returned;
+
+  int  preextrapolate;
+  int  eofflag;
+
+  long lW;
+  long W;
+  long nW;
+  long centerW;
+
+  ogg_int64_t granulepos;
+  ogg_int64_t sequence;
+
+  ogg_int64_t glue_bits;
+  ogg_int64_t time_bits;
+  ogg_int64_t floor_bits;
+  ogg_int64_t res_bits;
+
+  void       *backend_state;
+} vorbis_dsp_state;
+
+typedef struct vorbis_block{
+  /* necessary stream state for linking to the framing abstraction */
+  float  **pcm;       /* this is a pointer into local storage */
+  oggpack_buffer opb;
+
+  long  lW;
+  long  W;
+  long  nW;
+  int   pcmend;
+  int   mode;
+
+  int         eofflag;
+  ogg_int64_t granulepos;
+  ogg_int64_t sequence;
+  vorbis_dsp_state *vd; /* For read-only access of configuration */
+
+  /* local storage to avoid remallocing; it's up to the mapping to
+     structure it */
+  void               *localstore;
+  long                localtop;
+  long                localalloc;
+  long                totaluse;
+  struct alloc_chain *reap;
+
+  /* bitmetrics for the frame */
+  long glue_bits;
+  long time_bits;
+  long floor_bits;
+  long res_bits;
+
+  void *internal;
+
+} vorbis_block;
+
+/* vorbis_block is a single block of data to be processed as part of
+the analysis/synthesis stream; it belongs to a specific logical
+bitstream, but is independent from other vorbis_blocks belonging to
+that logical bitstream. *************************************************/
+
+struct alloc_chain{
+  void *ptr;
+  struct alloc_chain *next;
+};
+
+/* vorbis_info contains all the setup information specific to the
+   specific compression/decompression mode in progress (eg,
+   psychoacoustic settings, channel setup, options, codebook
+   etc). vorbis_info and substructures are in backends.h.
+*********************************************************************/
+
+/* the comments are not part of vorbis_info so that vorbis_info can be
+   static storage */
+typedef struct vorbis_comment{
+  /* unlimited user comment fields.  libvorbis writes 'libvorbis'
+     whatever vendor is set to in encode */
+  char **user_comments;
+  int   *comment_lengths;
+  int    comments;
+  char  *vendor;
+
+} vorbis_comment;
+
+
+/* libvorbis encodes in two abstraction layers; first we perform DSP
+   and produce a packet (see docs/analysis.txt).  The packet is then
+   coded into a framed OggSquish bitstream by the second layer (see
+   docs/framing.txt).  Decode is the reverse process; we sync/frame
+   the bitstream and extract individual packets, then decode the
+   packet back into PCM audio.
+
+   The extra framing/packetizing is used in streaming formats, such as
+   files.  Over the net (such as with UDP), the framing and
+   packetization aren't necessary as they're provided by the transport
+   and the streaming layer is not used */
+
+/* Vorbis PRIMITIVES: general ***************************************/
+
+extern void     vorbis_info_init(vorbis_info *vi);
+extern void     vorbis_info_clear(vorbis_info *vi);
+extern int      vorbis_info_blocksize(vorbis_info *vi,int zo);
+extern void     vorbis_comment_init(vorbis_comment *vc);
+extern void     vorbis_comment_add(vorbis_comment *vc, const char *comment);
+extern void     vorbis_comment_add_tag(vorbis_comment *vc,
+                                       const char *tag, const char *contents);
+extern char    *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count);
+extern int      vorbis_comment_query_count(vorbis_comment *vc, const char *tag);
+extern void     vorbis_comment_clear(vorbis_comment *vc);
+
+extern int      vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb);
+extern int      vorbis_block_clear(vorbis_block *vb);
+extern void     vorbis_dsp_clear(vorbis_dsp_state *v);
+extern double   vorbis_granule_time(vorbis_dsp_state *v,
+                                    ogg_int64_t granulepos);
+
+extern const char *vorbis_version_string(void);
+
+/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/
+
+extern int      vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi);
+extern int      vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op);
+extern int      vorbis_analysis_headerout(vorbis_dsp_state *v,
+                                          vorbis_comment *vc,
+                                          ogg_packet *op,
+                                          ogg_packet *op_comm,
+                                          ogg_packet *op_code);
+extern float  **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals);
+extern int      vorbis_analysis_wrote(vorbis_dsp_state *v,int vals);
+extern int      vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb);
+extern int      vorbis_analysis(vorbis_block *vb,ogg_packet *op);
+
+extern int      vorbis_bitrate_addblock(vorbis_block *vb);
+extern int      vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,
+                                           ogg_packet *op);
+
+/* Vorbis PRIMITIVES: synthesis layer *******************************/
+extern int      vorbis_synthesis_idheader(ogg_packet *op);
+extern int      vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,
+                                          ogg_packet *op);
+
+extern int      vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi);
+extern int      vorbis_synthesis_restart(vorbis_dsp_state *v);
+extern int      vorbis_synthesis(vorbis_block *vb,ogg_packet *op);
+extern int      vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op);
+extern int      vorbis_synthesis_samplecount(vorbis_dsp_state *v);
+extern int      vorbis_synthesis_blockin(vorbis_dsp_state *v, vorbis_block *vb);
+extern int      vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm);
+extern int      vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm);
+extern int      vorbis_synthesis_read(vorbis_dsp_state *v,int samples);
+extern long     vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op);
+
+extern int      vorbis_synthesis_halfrate(vorbis_info *v,int flag);
+extern int      vorbis_synthesis_halfrate_p(vorbis_info *v);
+
+/* Vorbis ERRORS and return codes ***********************************/
+
+#define OV_FALSE      -1
+#define OV_EOF        -2
+#define OV_HOLE       -3
+
+#define OV_EREAD      -128
+#define OV_EFAULT     -129
+#define OV_EIMPL      -130
+#define OV_EINVAL     -131
+#define OV_ENOTVORBIS -132
+#define OV_EBADHEADER -133
+#define OV_EVERSION   -134
+#define OV_ENOTAUDIO  -135
+#define OV_EBADPACKET -136
+#define OV_EBADLINK   -137
+#define OV_ENOSEEK    -138
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+

+ 436 - 0
liboggvorbis/include/vorbis/vorbisenc.h

@@ -0,0 +1,436 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: vorbis encode-engine setup
+ last mod: $Id: vorbisenc.h 17021 2010-03-24 09:29:41Z xiphmont $
+
+ ********************************************************************/
+
+/** \file
+ * Libvorbisenc is a convenient API for setting up an encoding
+ * environment using libvorbis. Libvorbisenc encapsulates the
+ * actions needed to set up the encoder properly.
+ */
+
+#ifndef _OV_ENC_H_
+#define _OV_ENC_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#include "codec.h"
+
+/**
+ * This is the primary function within libvorbisenc for setting up managed
+ * bitrate modes.
+ *
+ * Before this function is called, the \ref vorbis_info
+ * struct should be initialized by using vorbis_info_init() from the libvorbis
+ * API.  After encoding, vorbis_info_clear() should be called.
+ *
+ * The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set
+ * constraints for the encoded file.  This function uses these settings to
+ * select the appropriate encoding mode and set it up.
+ *
+ * \param vi               Pointer to an initialized \ref vorbis_info struct.
+ * \param channels         The number of channels to be encoded.
+ * \param rate             The sampling rate of the source audio.
+ * \param max_bitrate      Desired maximum bitrate (limit). -1 indicates unset.
+ * \param nominal_bitrate  Desired average, or central, bitrate. -1 indicates unset.
+ * \param min_bitrate      Desired minimum bitrate. -1 indicates unset.
+ *
+ * \return Zero for success, and negative values for failure.
+ *
+ * \retval 0          Success.
+ * \retval OV_EFAULT  Internal logic fault; indicates a bug or heap/stack corruption.
+ * \retval OV_EINVAL  Invalid setup request, eg, out of range argument.
+ * \retval OV_EIMPL   Unimplemented mode; unable to comply with bitrate request.
+ */
+extern int vorbis_encode_init(vorbis_info *vi,
+                              long channels,
+                              long rate,
+
+                              long max_bitrate,
+                              long nominal_bitrate,
+                              long min_bitrate);
+
+/**
+ * This function performs step-one of a three-step bitrate-managed encode
+ * setup.  It functions similarly to the one-step setup performed by \ref
+ * vorbis_encode_init but allows an application to make further encode setup
+ * tweaks using \ref vorbis_encode_ctl before finally calling \ref
+ * vorbis_encode_setup_init to complete the setup process.
+ *
+ * Before this function is called, the \ref vorbis_info struct should be
+ * initialized by using vorbis_info_init() from the libvorbis API.  After
+ * encoding, vorbis_info_clear() should be called.
+ *
+ * The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set
+ * constraints for the encoded file.  This function uses these settings to
+ * select the appropriate encoding mode and set it up.
+ *
+ * \param vi                Pointer to an initialized vorbis_info struct.
+ * \param channels          The number of channels to be encoded.
+ * \param rate              The sampling rate of the source audio.
+ * \param max_bitrate       Desired maximum bitrate (limit). -1 indicates unset.
+ * \param nominal_bitrate   Desired average, or central, bitrate. -1 indicates unset.
+ * \param min_bitrate       Desired minimum bitrate. -1 indicates unset.
+ *
+ * \return Zero for success, and negative for failure.
+ *
+ * \retval 0           Success
+ * \retval OV_EFAULT   Internal logic fault; indicates a bug or heap/stack corruption.
+ * \retval OV_EINVAL   Invalid setup request, eg, out of range argument.
+ * \retval OV_EIMPL    Unimplemented mode; unable to comply with bitrate request.
+ */
+extern int vorbis_encode_setup_managed(vorbis_info *vi,
+                                       long channels,
+                                       long rate,
+
+                                       long max_bitrate,
+                                       long nominal_bitrate,
+                                       long min_bitrate);
+
+/**
+ * This function performs step-one of a three-step variable bitrate
+ * (quality-based) encode setup.  It functions similarly to the one-step setup
+ * performed by \ref vorbis_encode_init_vbr() but allows an application to
+ * make further encode setup tweaks using \ref vorbis_encode_ctl() before
+ * finally calling \ref vorbis_encode_setup_init to complete the setup
+ * process.
+ *
+ * Before this function is called, the \ref vorbis_info struct should be
+ * initialized by using \ref vorbis_info_init() from the libvorbis API.  After
+ * encoding, vorbis_info_clear() should be called.
+ *
+ * \param vi        Pointer to an initialized vorbis_info struct.
+ * \param channels  The number of channels to be encoded.
+ * \param rate      The sampling rate of the source audio.
+ * \param quality   Desired quality level, currently from -0.1 to 1.0 (lo to hi).
+ *
+ * \return Zero for success, and negative values for failure.
+ *
+ * \retval  0          Success
+ * \retval  OV_EFAULT  Internal logic fault; indicates a bug or heap/stack corruption.
+ * \retval  OV_EINVAL  Invalid setup request, eg, out of range argument.
+ * \retval  OV_EIMPL   Unimplemented mode; unable to comply with quality level request.
+ */
+extern int vorbis_encode_setup_vbr(vorbis_info *vi,
+                                  long channels,
+                                  long rate,
+
+                                  float quality
+                                  );
+
+/**
+ * This is the primary function within libvorbisenc for setting up variable
+ * bitrate ("quality" based) modes.
+ *
+ *
+ * Before this function is called, the vorbis_info struct should be
+ * initialized by using vorbis_info_init() from the libvorbis API. After
+ * encoding, vorbis_info_clear() should be called.
+ *
+ * \param vi           Pointer to an initialized vorbis_info struct.
+ * \param channels     The number of channels to be encoded.
+ * \param rate         The sampling rate of the source audio.
+ * \param base_quality Desired quality level, currently from -0.1 to 1.0 (lo to hi).
+ *
+ *
+ * \return Zero for success, or a negative number for failure.
+ *
+ * \retval 0           Success
+ * \retval OV_EFAULT   Internal logic fault; indicates a bug or heap/stack corruption.
+ * \retval OV_EINVAL   Invalid setup request, eg, out of range argument.
+ * \retval OV_EIMPL    Unimplemented mode; unable to comply with quality level request.
+ */
+extern int vorbis_encode_init_vbr(vorbis_info *vi,
+                                  long channels,
+                                  long rate,
+
+                                  float base_quality
+                                  );
+
+/**
+ * This function performs the last stage of three-step encoding setup, as
+ * described in the API overview under managed bitrate modes.
+ *
+ * Before this function is called, the \ref vorbis_info struct should be
+ * initialized by using vorbis_info_init() from the libvorbis API, one of
+ * \ref vorbis_encode_setup_managed() or \ref vorbis_encode_setup_vbr() called to
+ * initialize the high-level encoding setup, and \ref vorbis_encode_ctl()
+ * called if necessary to make encoding setup changes.
+ * vorbis_encode_setup_init() finalizes the highlevel encoding structure into
+ * a complete encoding setup after which the application may make no further
+ * setup changes.
+ *
+ * After encoding, vorbis_info_clear() should be called.
+ *
+ * \param vi Pointer to an initialized \ref vorbis_info struct.
+ *
+ * \return Zero for success, and negative values for failure.
+ *
+ * \retval  0           Success.
+ * \retval  OV_EFAULT  Internal logic fault; indicates a bug or heap/stack corruption.
+ *
+ * \retval OV_EINVAL   Attempt to use vorbis_encode_setup_init() without first
+ * calling one of vorbis_encode_setup_managed() or vorbis_encode_setup_vbr() to
+ * initialize the high-level encoding setup
+ *
+ */
+extern int vorbis_encode_setup_init(vorbis_info *vi);
+
+/**
+ * This function implements a generic interface to miscellaneous encoder
+ * settings similar to the classic UNIX 'ioctl()' system call.  Applications
+ * may use vorbis_encode_ctl() to query or set bitrate management or quality
+ * mode details by using one of several \e request arguments detailed below.
+ * vorbis_encode_ctl() must be called after one of
+ * vorbis_encode_setup_managed() or vorbis_encode_setup_vbr().  When used
+ * to modify settings, \ref vorbis_encode_ctl() must be called before \ref
+ * vorbis_encode_setup_init().
+ *
+ * \param vi      Pointer to an initialized vorbis_info struct.
+ *
+ * \param number Specifies the desired action; See \ref encctlcodes "the list
+ * of available requests".
+ *
+ * \param arg void * pointing to a data structure matching the request
+ * argument.
+ *
+ * \retval 0          Success. Any further return information (such as the result of a
+ * query) is placed into the storage pointed to by *arg.
+ *
+ * \retval OV_EINVAL  Invalid argument, or an attempt to modify a setting after
+ * calling vorbis_encode_setup_init().
+ *
+ * \retval OV_EIMPL   Unimplemented or unknown request
+ */
+extern int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg);
+
+/**
+ * \deprecated This is a deprecated interface. Please use vorbis_encode_ctl()
+ * with the \ref ovectl_ratemanage2_arg struct and \ref
+ * OV_ECTL_RATEMANAGE2_GET and \ref OV_ECTL_RATEMANAGE2_SET calls in new code.
+ *
+ * The \ref ovectl_ratemanage_arg structure is used with vorbis_encode_ctl()
+ * and the \ref OV_ECTL_RATEMANAGE_GET, \ref OV_ECTL_RATEMANAGE_SET, \ref
+ * OV_ECTL_RATEMANAGE_AVG, \ref OV_ECTL_RATEMANAGE_HARD calls in order to
+ * query and modify specifics of the encoder's bitrate management
+ * configuration.
+*/
+struct ovectl_ratemanage_arg {
+  int    management_active; /**< nonzero if bitrate management is active*/
+/** hard lower limit (in kilobits per second) below which the stream bitrate
+    will never be allowed for any given bitrate_hard_window seconds of time.*/
+  long   bitrate_hard_min;
+/** hard upper limit (in kilobits per second) above which the stream bitrate
+    will never be allowed for any given bitrate_hard_window seconds of time.*/
+  long   bitrate_hard_max;
+/** the window period (in seconds) used to regulate the hard bitrate minimum
+    and maximum*/
+  double bitrate_hard_window;
+/** soft lower limit (in kilobits per second) below which the average bitrate
+    tracker will start nudging the bitrate higher.*/
+  long   bitrate_av_lo;
+/** soft upper limit (in kilobits per second) above which the average bitrate
+    tracker will start nudging the bitrate lower.*/
+  long   bitrate_av_hi;
+/** the window period (in seconds) used to regulate the average bitrate
+    minimum and maximum.*/
+  double bitrate_av_window;
+/** Regulates the relative centering of the average and hard windows; in
+    libvorbis 1.0 and 1.0.1, the hard window regulation overlapped but
+    followed the average window regulation. In libvorbis 1.1 a bit-reservoir
+    interface replaces the old windowing interface; the older windowing
+    interface is simulated and this field has no effect.*/
+  double bitrate_av_window_center;
+};
+
+/**
+ * \name struct ovectl_ratemanage2_arg
+ *
+ * The ovectl_ratemanage2_arg structure is used with vorbis_encode_ctl() and
+ * the OV_ECTL_RATEMANAGE2_GET and OV_ECTL_RATEMANAGE2_SET calls in order to
+ * query and modify specifics of the encoder's bitrate management
+ * configuration.
+ *
+*/
+struct ovectl_ratemanage2_arg {
+  int    management_active; /**< nonzero if bitrate management is active */
+/** Lower allowed bitrate limit in kilobits per second */
+  long   bitrate_limit_min_kbps;
+/** Upper allowed bitrate limit in kilobits per second */
+  long   bitrate_limit_max_kbps;
+  long   bitrate_limit_reservoir_bits; /**<Size of the bitrate reservoir in bits */
+/** Regulates the bitrate reservoir's preferred fill level in a range from 0.0
+ * to 1.0; 0.0 tries to bank bits to buffer against future bitrate spikes, 1.0
+ * buffers against future sudden drops in instantaneous bitrate. Default is
+ * 0.1
+ */
+  double bitrate_limit_reservoir_bias;
+/** Average bitrate setting in kilobits per second */
+  long   bitrate_average_kbps;
+/** Slew rate limit setting for average bitrate adjustment; sets the minimum
+ *  time in seconds the bitrate tracker may swing from one extreme to the
+ *  other when boosting or damping average bitrate.
+ */
+  double bitrate_average_damping;
+};
+
+
+/**
+ * \name vorbis_encode_ctl() codes
+ *
+ * \anchor encctlcodes
+ *
+ * These values are passed as the \c number parameter of vorbis_encode_ctl().
+ * The type of the referent of that function's \c arg pointer depends on these
+ * codes.
+ */
+/*@{*/
+
+/**
+ * Query the current encoder bitrate management setting.
+ *
+ *Argument: <tt>struct ovectl_ratemanage2_arg *</tt>
+ *
+ * Used to query the current encoder bitrate management setting. Also used to
+ * initialize fields of an ovectl_ratemanage2_arg structure for use with
+ * \ref OV_ECTL_RATEMANAGE2_SET.
+ */
+#define OV_ECTL_RATEMANAGE2_GET      0x14
+
+/**
+ * Set the current encoder bitrate management settings.
+ *
+ * Argument: <tt>struct ovectl_ratemanage2_arg *</tt>
+ *
+ * Used to set the current encoder bitrate management settings to the values
+ * listed in the ovectl_ratemanage2_arg. Passing a NULL pointer will disable
+ * bitrate management.
+*/
+#define OV_ECTL_RATEMANAGE2_SET      0x15
+
+/**
+ * Returns the current encoder hard-lowpass setting (kHz) in the double
+ * pointed to by arg.
+ *
+ * Argument: <tt>double *</tt>
+*/
+#define OV_ECTL_LOWPASS_GET          0x20
+
+/**
+ *  Sets the encoder hard-lowpass to the value (kHz) pointed to by arg. Valid
+ *  lowpass settings range from 2 to 99.
+ *
+ * Argument: <tt>double *</tt>
+*/
+#define OV_ECTL_LOWPASS_SET          0x21
+
+/**
+ *  Returns the current encoder impulse block setting in the double pointed
+ *  to by arg.
+ *
+ * Argument: <tt>double *</tt>
+*/
+#define OV_ECTL_IBLOCK_GET           0x30
+
+/**
+ *  Sets the impulse block bias to the the value pointed to by arg.
+ *
+ * Argument: <tt>double *</tt>
+ *
+ *  Valid range is -15.0 to 0.0 [default]. A negative impulse block bias will
+ *  direct to encoder to use more bits when incoding short blocks that contain
+ *  strong impulses, thus improving the accuracy of impulse encoding.
+ */
+#define OV_ECTL_IBLOCK_SET           0x31
+
+/**
+ *  Returns the current encoder coupling setting in the int pointed
+ *  to by arg.
+ *
+ * Argument: <tt>int *</tt>
+*/
+#define OV_ECTL_COUPLING_GET         0x40
+
+/**
+ *  Enables/disables channel coupling in multichannel encoding according to arg.
+ *
+ * Argument: <tt>int *</tt>
+ *
+ *  Zero disables channel coupling for multichannel inputs, nonzer enables
+ *  channel coupling.  Setting has no effect on monophonic encoding or
+ *  multichannel counts that do not offer coupling.  At present, coupling is
+ *  available for stereo and 5.1 encoding.
+ */
+#define OV_ECTL_COUPLING_SET         0x41
+
+  /* deprecated rate management supported only for compatibility */
+
+/**
+ * Old interface to querying bitrate management settings.
+ *
+ * Deprecated after move to bit-reservoir style management in 1.1 rendered
+ * this interface partially obsolete.
+
+ * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_GET instead.
+ *
+ * Argument: <tt>struct ovectl_ratemanage_arg *</tt>
+ */
+#define OV_ECTL_RATEMANAGE_GET       0x10
+/**
+ * Old interface to modifying bitrate management settings.
+ *
+ *  deprecated after move to bit-reservoir style management in 1.1 rendered
+ *  this interface partially obsolete.
+ *
+ * \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead.
+ *
+ * Argument: <tt>struct ovectl_ratemanage_arg *</tt>
+ */
+#define OV_ECTL_RATEMANAGE_SET       0x11
+/**
+ * Old interface to setting average-bitrate encoding mode.
+ *
+ * Deprecated after move to bit-reservoir style management in 1.1 rendered
+ * this interface partially obsolete.
+ *
+ *  \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead.
+ *
+ * Argument: <tt>struct ovectl_ratemanage_arg *</tt>
+ */
+#define OV_ECTL_RATEMANAGE_AVG       0x12
+/**
+ * Old interface to setting bounded-bitrate encoding modes.
+ *
+ * deprecated after move to bit-reservoir style management in 1.1 rendered
+ * this interface partially obsolete.
+ *
+ *  \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead.
+ *
+ * Argument: <tt>struct ovectl_ratemanage_arg *</tt>
+ */
+#define OV_ECTL_RATEMANAGE_HARD      0x13
+
+/*@}*/
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif

+ 206 - 0
liboggvorbis/include/vorbis/vorbisfile.h

@@ -0,0 +1,206 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: stdio-based convenience library for opening/seeking/decoding
+ last mod: $Id: vorbisfile.h 17182 2010-04-29 03:48:32Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _OV_FILE_H_
+#define _OV_FILE_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#include <stdio.h>
+#include "codec.h"
+
+/* The function prototypes for the callbacks are basically the same as for
+ * the stdio functions fread, fseek, fclose, ftell.
+ * The one difference is that the FILE * arguments have been replaced with
+ * a void * - this is to be used as a pointer to whatever internal data these
+ * functions might need. In the stdio case, it's just a FILE * cast to a void *
+ *
+ * If you use other functions, check the docs for these functions and return
+ * the right values. For seek_func(), you *MUST* return -1 if the stream is
+ * unseekable
+ */
+typedef struct {
+  size_t (*read_func)  (void *ptr, size_t size, size_t nmemb, void *datasource);
+  int    (*seek_func)  (void *datasource, ogg_int64_t offset, int whence);
+  int    (*close_func) (void *datasource);
+  long   (*tell_func)  (void *datasource);
+} ov_callbacks;
+
+#ifndef OV_EXCLUDE_STATIC_CALLBACKS
+
+/* a few sets of convenient callbacks, especially for use under
+ * Windows where ov_open_callbacks() should always be used instead of
+ * ov_open() to avoid problems with incompatible crt.o version linking
+ * issues. */
+
+static int _ov_header_fseek_wrap(FILE *f,ogg_int64_t off,int whence){
+  if(f==NULL)return(-1);
+
+#ifdef __MINGW32__
+  return fseeko64(f,off,whence);
+#elif defined (_WIN32)
+  return _fseeki64(f,off,whence);
+#else
+  return fseek(f,off,whence);
+#endif
+}
+
+/* These structs below (OV_CALLBACKS_DEFAULT etc) are defined here as
+ * static data. That means that every file which includes this header
+ * will get its own copy of these structs whether it uses them or
+ * not unless it #defines OV_EXCLUDE_STATIC_CALLBACKS.
+ * These static symbols are essential on platforms such as Windows on
+ * which several different versions of stdio support may be linked to
+ * by different DLLs, and we need to be certain we know which one
+ * we're using (the same one as the main application).
+ */
+
+static ov_callbacks OV_CALLBACKS_DEFAULT = {
+  (size_t (*)(void *, size_t, size_t, void *))  fread,
+  (int (*)(void *, ogg_int64_t, int))           _ov_header_fseek_wrap,
+  (int (*)(void *))                             fclose,
+  (long (*)(void *))                            ftell
+};
+
+static ov_callbacks OV_CALLBACKS_NOCLOSE = {
+  (size_t (*)(void *, size_t, size_t, void *))  fread,
+  (int (*)(void *, ogg_int64_t, int))           _ov_header_fseek_wrap,
+  (int (*)(void *))                             NULL,
+  (long (*)(void *))                            ftell
+};
+
+static ov_callbacks OV_CALLBACKS_STREAMONLY = {
+  (size_t (*)(void *, size_t, size_t, void *))  fread,
+  (int (*)(void *, ogg_int64_t, int))           NULL,
+  (int (*)(void *))                             fclose,
+  (long (*)(void *))                            NULL
+};
+
+static ov_callbacks OV_CALLBACKS_STREAMONLY_NOCLOSE = {
+  (size_t (*)(void *, size_t, size_t, void *))  fread,
+  (int (*)(void *, ogg_int64_t, int))           NULL,
+  (int (*)(void *))                             NULL,
+  (long (*)(void *))                            NULL
+};
+
+#endif
+
+#define  NOTOPEN   0
+#define  PARTOPEN  1
+#define  OPENED    2
+#define  STREAMSET 3
+#define  INITSET   4
+
+typedef struct OggVorbis_File {
+  void            *datasource; /* Pointer to a FILE *, etc. */
+  int              seekable;
+  ogg_int64_t      offset;
+  ogg_int64_t      end;
+  ogg_sync_state   oy;
+
+  /* If the FILE handle isn't seekable (eg, a pipe), only the current
+     stream appears */
+  int              links;
+  ogg_int64_t     *offsets;
+  ogg_int64_t     *dataoffsets;
+  long            *serialnos;
+  ogg_int64_t     *pcmlengths; /* overloaded to maintain binary
+                                  compatibility; x2 size, stores both
+                                  beginning and end values */
+  vorbis_info     *vi;
+  vorbis_comment  *vc;
+
+  /* Decoding working state local storage */
+  ogg_int64_t      pcm_offset;
+  int              ready_state;
+  long             current_serialno;
+  int              current_link;
+
+  double           bittrack;
+  double           samptrack;
+
+  ogg_stream_state os; /* take physical pages, weld into a logical
+                          stream of packets */
+  vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
+  vorbis_block     vb; /* local working space for packet->PCM decode */
+
+  ov_callbacks callbacks;
+
+} OggVorbis_File;
+
+
+extern int ov_clear(OggVorbis_File *vf);
+extern int ov_fopen(const char *path,OggVorbis_File *vf);
+extern int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes);
+extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf,
+                const char *initial, long ibytes, ov_callbacks callbacks);
+
+extern int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes);
+extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf,
+                const char *initial, long ibytes, ov_callbacks callbacks);
+extern int ov_test_open(OggVorbis_File *vf);
+
+extern long ov_bitrate(OggVorbis_File *vf,int i);
+extern long ov_bitrate_instant(OggVorbis_File *vf);
+extern long ov_streams(OggVorbis_File *vf);
+extern long ov_seekable(OggVorbis_File *vf);
+extern long ov_serialnumber(OggVorbis_File *vf,int i);
+
+extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i);
+extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i);
+extern double ov_time_total(OggVorbis_File *vf,int i);
+
+extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_time_seek(OggVorbis_File *vf,double pos);
+extern int ov_time_seek_page(OggVorbis_File *vf,double pos);
+
+extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos);
+extern int ov_time_seek_lap(OggVorbis_File *vf,double pos);
+extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos);
+
+extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf);
+extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf);
+extern double ov_time_tell(OggVorbis_File *vf);
+
+extern vorbis_info *ov_info(OggVorbis_File *vf,int link);
+extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link);
+
+extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples,
+                          int *bitstream);
+extern long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
+                          int bigendianp,int word,int sgned,int *bitstream,
+                          void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param);
+extern long ov_read(OggVorbis_File *vf,char *buffer,int length,
+                    int bigendianp,int word,int sgned,int *bitstream);
+extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2);
+
+extern int ov_halfrate(OggVorbis_File *vf,int flag);
+extern int ov_halfrate_p(OggVorbis_File *vf);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+

+ 120 - 0
liboggvorbis/src/analysis.c

@@ -0,0 +1,120 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: single-block PCM analysis mode dispatch
+ last mod: $Id: analysis.c 16226 2009-07-08 06:43:49Z xiphmont $
+
+ ********************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+#include "registry.h"
+#include "scales.h"
+#include "os.h"
+#include "misc.h"
+
+/* decides between modes, dispatches to the appropriate mapping. */
+int vorbis_analysis(vorbis_block *vb, ogg_packet *op){
+  int ret,i;
+  vorbis_block_internal *vbi=vb->internal;
+
+  vb->glue_bits=0;
+  vb->time_bits=0;
+  vb->floor_bits=0;
+  vb->res_bits=0;
+
+  /* first things first.  Make sure encode is ready */
+  for(i=0;i<PACKETBLOBS;i++)
+    oggpack_reset(vbi->packetblob[i]);
+
+  /* we only have one mapping type (0), and we let the mapping code
+     itself figure out what soft mode to use.  This allows easier
+     bitrate management */
+
+  if((ret=_mapping_P[0]->forward(vb)))
+    return(ret);
+
+  if(op){
+    if(vorbis_bitrate_managed(vb))
+      /* The app is using a bitmanaged mode... but not using the
+         bitrate management interface. */
+      return(OV_EINVAL);
+
+    op->packet=oggpack_get_buffer(&vb->opb);
+    op->bytes=oggpack_bytes(&vb->opb);
+    op->b_o_s=0;
+    op->e_o_s=vb->eofflag;
+    op->granulepos=vb->granulepos;
+    op->packetno=vb->sequence; /* for sake of completeness */
+  }
+  return(0);
+}
+
+#ifdef ANALYSIS
+int analysis_noisy=1;
+
+/* there was no great place to put this.... */
+void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,ogg_int64_t off){
+  int j;
+  FILE *of;
+  char buffer[80];
+
+  sprintf(buffer,"%s_%d.m",base,i);
+  of=fopen(buffer,"w");
+
+  if(!of)perror("failed to open data dump file");
+
+  for(j=0;j<n;j++){
+    if(bark){
+      float b=toBARK((4000.f*j/n)+.25);
+      fprintf(of,"%f ",b);
+    }else
+      if(off!=0)
+        fprintf(of,"%f ",(double)(j+off)/8000.);
+      else
+        fprintf(of,"%f ",(double)j);
+
+    if(dB){
+      float val;
+      if(v[j]==0.)
+        val=-140.;
+      else
+        val=todB(v+j);
+      fprintf(of,"%f\n",val);
+    }else{
+      fprintf(of,"%f\n",v[j]);
+    }
+  }
+  fclose(of);
+}
+
+void _analysis_output(char *base,int i,float *v,int n,int bark,int dB,
+                      ogg_int64_t off){
+  if(analysis_noisy)_analysis_output_always(base,i,v,n,bark,dB,off);
+}
+
+#endif
+
+
+
+
+
+
+
+
+
+
+

+ 144 - 0
liboggvorbis/src/backends.h

@@ -0,0 +1,144 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: libvorbis backend and mapping structures; needed for
+           static mode headers
+ last mod: $Id: backends.h 16962 2010-03-11 07:30:34Z xiphmont $
+
+ ********************************************************************/
+
+/* this is exposed up here because we need it for static modes.
+   Lookups for each backend aren't exposed because there's no reason
+   to do so */
+
+#ifndef _vorbis_backend_h_
+#define _vorbis_backend_h_
+
+#include "codec_internal.h"
+
+/* this would all be simpler/shorter with templates, but.... */
+/* Floor backend generic *****************************************/
+typedef struct{
+  void                   (*pack)  (vorbis_info_floor *,oggpack_buffer *);
+  vorbis_info_floor     *(*unpack)(vorbis_info *,oggpack_buffer *);
+  vorbis_look_floor     *(*look)  (vorbis_dsp_state *,vorbis_info_floor *);
+  void (*free_info) (vorbis_info_floor *);
+  void (*free_look) (vorbis_look_floor *);
+  void *(*inverse1)  (struct vorbis_block *,vorbis_look_floor *);
+  int   (*inverse2)  (struct vorbis_block *,vorbis_look_floor *,
+                     void *buffer,float *);
+} vorbis_func_floor;
+
+typedef struct{
+  int   order;
+  long  rate;
+  long  barkmap;
+
+  int   ampbits;
+  int   ampdB;
+
+  int   numbooks; /* <= 16 */
+  int   books[16];
+
+  float lessthan;     /* encode-only config setting hacks for libvorbis */
+  float greaterthan;  /* encode-only config setting hacks for libvorbis */
+
+} vorbis_info_floor0;
+
+
+#define VIF_POSIT 63
+#define VIF_CLASS 16
+#define VIF_PARTS 31
+typedef struct{
+  int   partitions;                /* 0 to 31 */
+  int   partitionclass[VIF_PARTS]; /* 0 to 15 */
+
+  int   class_dim[VIF_CLASS];        /* 1 to 8 */
+  int   class_subs[VIF_CLASS];       /* 0,1,2,3 (bits: 1<<n poss) */
+  int   class_book[VIF_CLASS];       /* subs ^ dim entries */
+  int   class_subbook[VIF_CLASS][8]; /* [VIF_CLASS][subs] */
+
+
+  int   mult;                      /* 1 2 3 or 4 */
+  int   postlist[VIF_POSIT+2];    /* first two implicit */
+
+
+  /* encode side analysis parameters */
+  float maxover;
+  float maxunder;
+  float maxerr;
+
+  float twofitweight;
+  float twofitatten;
+
+  int   n;
+
+} vorbis_info_floor1;
+
+/* Residue backend generic *****************************************/
+typedef struct{
+  void                 (*pack)  (vorbis_info_residue *,oggpack_buffer *);
+  vorbis_info_residue *(*unpack)(vorbis_info *,oggpack_buffer *);
+  vorbis_look_residue *(*look)  (vorbis_dsp_state *,
+                                 vorbis_info_residue *);
+  void (*free_info)    (vorbis_info_residue *);
+  void (*free_look)    (vorbis_look_residue *);
+  long **(*class)      (struct vorbis_block *,vorbis_look_residue *,
+                        int **,int *,int);
+  int  (*forward)      (oggpack_buffer *,struct vorbis_block *,
+                        vorbis_look_residue *,
+                        int **,int *,int,long **,int);
+  int  (*inverse)      (struct vorbis_block *,vorbis_look_residue *,
+                        float **,int *,int);
+} vorbis_func_residue;
+
+typedef struct vorbis_info_residue0{
+/* block-partitioned VQ coded straight residue */
+  long  begin;
+  long  end;
+
+  /* first stage (lossless partitioning) */
+  int    grouping;         /* group n vectors per partition */
+  int    partitions;       /* possible codebooks for a partition */
+  int    partvals;         /* partitions ^ groupbook dim */
+  int    groupbook;        /* huffbook for partitioning */
+  int    secondstages[64]; /* expanded out to pointers in lookup */
+  int    booklist[512];    /* list of second stage books */
+
+  const int classmetric1[64];
+  const int classmetric2[64];
+} vorbis_info_residue0;
+
+/* Mapping backend generic *****************************************/
+typedef struct{
+  void                 (*pack)  (vorbis_info *,vorbis_info_mapping *,
+                                 oggpack_buffer *);
+  vorbis_info_mapping *(*unpack)(vorbis_info *,oggpack_buffer *);
+  void (*free_info)    (vorbis_info_mapping *);
+  int  (*forward)      (struct vorbis_block *vb);
+  int  (*inverse)      (struct vorbis_block *vb,vorbis_info_mapping *);
+} vorbis_func_mapping;
+
+typedef struct vorbis_info_mapping0{
+  int   submaps;  /* <= 16 */
+  int   chmuxlist[256];   /* up to 256 channels in a Vorbis stream */
+
+  int   floorsubmap[16];   /* [mux] submap to floors */
+  int   residuesubmap[16]; /* [mux] submap to residue */
+
+  int   coupling_steps;
+  int   coupling_mag[256];
+  int   coupling_ang[256];
+
+} vorbis_info_mapping0;
+
+#endif

+ 253 - 0
liboggvorbis/src/bitrate.c

@@ -0,0 +1,253 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: bitrate tracking and management
+ last mod: $Id: bitrate.c 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+#include "os.h"
+#include "misc.h"
+#include "bitrate.h"
+
+/* compute bitrate tracking setup  */
+void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bm){
+  codec_setup_info *ci=vi->codec_setup;
+  bitrate_manager_info *bi=&ci->bi;
+
+  memset(bm,0,sizeof(*bm));
+
+  if(bi && (bi->reservoir_bits>0)){
+    long ratesamples=vi->rate;
+    int  halfsamples=ci->blocksizes[0]>>1;
+
+    bm->short_per_long=ci->blocksizes[1]/ci->blocksizes[0];
+    bm->managed=1;
+
+    bm->avg_bitsper= rint(1.*bi->avg_rate*halfsamples/ratesamples);
+    bm->min_bitsper= rint(1.*bi->min_rate*halfsamples/ratesamples);
+    bm->max_bitsper= rint(1.*bi->max_rate*halfsamples/ratesamples);
+
+    bm->avgfloat=PACKETBLOBS/2;
+
+    /* not a necessary fix, but one that leads to a more balanced
+       typical initialization */
+    {
+      long desired_fill=bi->reservoir_bits*bi->reservoir_bias;
+      bm->minmax_reservoir=desired_fill;
+      bm->avg_reservoir=desired_fill;
+    }
+
+  }
+}
+
+void vorbis_bitrate_clear(bitrate_manager_state *bm){
+  memset(bm,0,sizeof(*bm));
+  return;
+}
+
+int vorbis_bitrate_managed(vorbis_block *vb){
+  vorbis_dsp_state      *vd=vb->vd;
+  private_state         *b=vd->backend_state;
+  bitrate_manager_state *bm=&b->bms;
+
+  if(bm && bm->managed)return(1);
+  return(0);
+}
+
+/* finish taking in the block we just processed */
+int vorbis_bitrate_addblock(vorbis_block *vb){
+  vorbis_block_internal *vbi=vb->internal;
+  vorbis_dsp_state      *vd=vb->vd;
+  private_state         *b=vd->backend_state;
+  bitrate_manager_state *bm=&b->bms;
+  vorbis_info           *vi=vd->vi;
+  codec_setup_info      *ci=vi->codec_setup;
+  bitrate_manager_info  *bi=&ci->bi;
+
+  int  choice=rint(bm->avgfloat);
+  long this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
+  long min_target_bits=(vb->W?bm->min_bitsper*bm->short_per_long:bm->min_bitsper);
+  long max_target_bits=(vb->W?bm->max_bitsper*bm->short_per_long:bm->max_bitsper);
+  int  samples=ci->blocksizes[vb->W]>>1;
+  long desired_fill=bi->reservoir_bits*bi->reservoir_bias;
+  if(!bm->managed){
+    /* not a bitrate managed stream, but for API simplicity, we'll
+       buffer the packet to keep the code path clean */
+
+    if(bm->vb)return(-1); /* one has been submitted without
+                             being claimed */
+    bm->vb=vb;
+    return(0);
+  }
+
+  bm->vb=vb;
+
+  /* look ahead for avg floater */
+  if(bm->avg_bitsper>0){
+    double slew=0.;
+    long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper);
+    double slewlimit= 15./bi->slew_damp;
+
+    /* choosing a new floater:
+       if we're over target, we slew down
+       if we're under target, we slew up
+
+       choose slew as follows: look through packetblobs of this frame
+       and set slew as the first in the appropriate direction that
+       gives us the slew we want.  This may mean no slew if delta is
+       already favorable.
+
+       Then limit slew to slew max */
+
+    if(bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){
+      while(choice>0 && this_bits>avg_target_bits &&
+            bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){
+        choice--;
+        this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
+      }
+    }else if(bm->avg_reservoir+(this_bits-avg_target_bits)<desired_fill){
+      while(choice+1<PACKETBLOBS && this_bits<avg_target_bits &&
+            bm->avg_reservoir+(this_bits-avg_target_bits)<desired_fill){
+        choice++;
+        this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
+      }
+    }
+
+    slew=rint(choice-bm->avgfloat)/samples*vi->rate;
+    if(slew<-slewlimit)slew=-slewlimit;
+    if(slew>slewlimit)slew=slewlimit;
+    choice=rint(bm->avgfloat+= slew/vi->rate*samples);
+    this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
+  }
+
+
+
+  /* enforce min(if used) on the current floater (if used) */
+  if(bm->min_bitsper>0){
+    /* do we need to force the bitrate up? */
+    if(this_bits<min_target_bits){
+      while(bm->minmax_reservoir-(min_target_bits-this_bits)<0){
+        choice++;
+        if(choice>=PACKETBLOBS)break;
+        this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
+      }
+    }
+  }
+
+  /* enforce max (if used) on the current floater (if used) */
+  if(bm->max_bitsper>0){
+    /* do we need to force the bitrate down? */
+    if(this_bits>max_target_bits){
+      while(bm->minmax_reservoir+(this_bits-max_target_bits)>bi->reservoir_bits){
+        choice--;
+        if(choice<0)break;
+        this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
+      }
+    }
+  }
+
+  /* Choice of packetblobs now made based on floater, and min/max
+     requirements. Now boundary check extreme choices */
+
+  if(choice<0){
+    /* choosing a smaller packetblob is insufficient to trim bitrate.
+       frame will need to be truncated */
+    long maxsize=(max_target_bits+(bi->reservoir_bits-bm->minmax_reservoir))/8;
+    bm->choice=choice=0;
+
+    if(oggpack_bytes(vbi->packetblob[choice])>maxsize){
+
+      oggpack_writetrunc(vbi->packetblob[choice],maxsize*8);
+      this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
+    }
+  }else{
+    long minsize=(min_target_bits-bm->minmax_reservoir+7)/8;
+    if(choice>=PACKETBLOBS)
+      choice=PACKETBLOBS-1;
+
+    bm->choice=choice;
+
+    /* prop up bitrate according to demand. pad this frame out with zeroes */
+    minsize-=oggpack_bytes(vbi->packetblob[choice]);
+    while(minsize-->0)oggpack_write(vbi->packetblob[choice],0,8);
+    this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
+
+  }
+
+  /* now we have the final packet and the final packet size.  Update statistics */
+  /* min and max reservoir */
+  if(bm->min_bitsper>0 || bm->max_bitsper>0){
+
+    if(max_target_bits>0 && this_bits>max_target_bits){
+      bm->minmax_reservoir+=(this_bits-max_target_bits);
+    }else if(min_target_bits>0 && this_bits<min_target_bits){
+      bm->minmax_reservoir+=(this_bits-min_target_bits);
+    }else{
+      /* inbetween; we want to take reservoir toward but not past desired_fill */
+      if(bm->minmax_reservoir>desired_fill){
+        if(max_target_bits>0){ /* logical bulletproofing against initialization state */
+          bm->minmax_reservoir+=(this_bits-max_target_bits);
+          if(bm->minmax_reservoir<desired_fill)bm->minmax_reservoir=desired_fill;
+        }else{
+          bm->minmax_reservoir=desired_fill;
+        }
+      }else{
+        if(min_target_bits>0){ /* logical bulletproofing against initialization state */
+          bm->minmax_reservoir+=(this_bits-min_target_bits);
+          if(bm->minmax_reservoir>desired_fill)bm->minmax_reservoir=desired_fill;
+        }else{
+          bm->minmax_reservoir=desired_fill;
+        }
+      }
+    }
+  }
+
+  /* avg reservoir */
+  if(bm->avg_bitsper>0){
+    long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper);
+    bm->avg_reservoir+=this_bits-avg_target_bits;
+  }
+
+  return(0);
+}
+
+int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,ogg_packet *op){
+  private_state         *b=vd->backend_state;
+  bitrate_manager_state *bm=&b->bms;
+  vorbis_block          *vb=bm->vb;
+  int                    choice=PACKETBLOBS/2;
+  if(!vb)return 0;
+
+  if(op){
+    vorbis_block_internal *vbi=vb->internal;
+
+    if(vorbis_bitrate_managed(vb))
+      choice=bm->choice;
+
+    op->packet=oggpack_get_buffer(vbi->packetblob[choice]);
+    op->bytes=oggpack_bytes(vbi->packetblob[choice]);
+    op->b_o_s=0;
+    op->e_o_s=vb->eofflag;
+    op->granulepos=vb->granulepos;
+    op->packetno=vb->sequence; /* for sake of completeness */
+  }
+
+  bm->vb=0;
+  return(1);
+}

+ 59 - 0
liboggvorbis/src/bitrate.h

@@ -0,0 +1,59 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: bitrate tracking and management
+ last mod: $Id: bitrate.h 13293 2007-07-24 00:09:47Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _V_BITRATE_H_
+#define _V_BITRATE_H_
+
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+#include "os.h"
+
+/* encode side bitrate tracking */
+typedef struct bitrate_manager_state {
+  int            managed;
+
+  long           avg_reservoir;
+  long           minmax_reservoir;
+  long           avg_bitsper;
+  long           min_bitsper;
+  long           max_bitsper;
+
+  long           short_per_long;
+  double         avgfloat;
+
+  vorbis_block  *vb;
+  int            choice;
+} bitrate_manager_state;
+
+typedef struct bitrate_manager_info{
+  long           avg_rate;
+  long           min_rate;
+  long           max_rate;
+  long           reservoir_bits;
+  double         reservoir_bias;
+
+  double         slew_damp;
+
+} bitrate_manager_info;
+
+extern void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bs);
+extern void vorbis_bitrate_clear(bitrate_manager_state *bs);
+extern int vorbis_bitrate_managed(vorbis_block *vb);
+extern int vorbis_bitrate_addblock(vorbis_block *vb);
+extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, ogg_packet *op);
+
+#endif

File diff suppressed because it is too large
+ 1088 - 0
liboggvorbis/src/bitwise.c


File diff suppressed because it is too large
+ 1050 - 0
liboggvorbis/src/block.c


File diff suppressed because it is too large
+ 12274 - 0
liboggvorbis/src/books/coupled/res_books_51.h


File diff suppressed because it is too large
+ 15783 - 0
liboggvorbis/src/books/coupled/res_books_stereo.h


File diff suppressed because it is too large
+ 1547 - 0
liboggvorbis/src/books/floor/floor_books.h


File diff suppressed because it is too large
+ 7758 - 0
liboggvorbis/src/books/uncoupled/res_books_uncoupled.h


+ 484 - 0
liboggvorbis/src/codebook.c

@@ -0,0 +1,484 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: basic codebook pack/unpack/code/decode operations
+ last mod: $Id: codebook.c 19057 2014-01-22 12:32:31Z xiphmont $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codebook.h"
+#include "scales.h"
+#include "misc.h"
+#include "os.h"
+
+/* packs the given codebook into the bitstream **************************/
+
+int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
+  long i,j;
+  int ordered=0;
+
+  /* first the basic parameters */
+  oggpack_write(opb,0x564342,24);
+  oggpack_write(opb,c->dim,16);
+  oggpack_write(opb,c->entries,24);
+
+  /* pack the codewords.  There are two packings; length ordered and
+     length random.  Decide between the two now. */
+
+  for(i=1;i<c->entries;i++)
+    if(c->lengthlist[i-1]==0 || c->lengthlist[i]<c->lengthlist[i-1])break;
+  if(i==c->entries)ordered=1;
+
+  if(ordered){
+    /* length ordered.  We only need to say how many codewords of
+       each length.  The actual codewords are generated
+       deterministically */
+
+    long count=0;
+    oggpack_write(opb,1,1);  /* ordered */
+    oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */
+
+    for(i=1;i<c->entries;i++){
+      char this=c->lengthlist[i];
+      char last=c->lengthlist[i-1];
+      if(this>last){
+        for(j=last;j<this;j++){
+          oggpack_write(opb,i-count,_ilog(c->entries-count));
+          count=i;
+        }
+      }
+    }
+    oggpack_write(opb,i-count,_ilog(c->entries-count));
+
+  }else{
+    /* length random.  Again, we don't code the codeword itself, just
+       the length.  This time, though, we have to encode each length */
+    oggpack_write(opb,0,1);   /* unordered */
+
+    /* algortihmic mapping has use for 'unused entries', which we tag
+       here.  The algorithmic mapping happens as usual, but the unused
+       entry has no codeword. */
+    for(i=0;i<c->entries;i++)
+      if(c->lengthlist[i]==0)break;
+
+    if(i==c->entries){
+      oggpack_write(opb,0,1); /* no unused entries */
+      for(i=0;i<c->entries;i++)
+        oggpack_write(opb,c->lengthlist[i]-1,5);
+    }else{
+      oggpack_write(opb,1,1); /* we have unused entries; thus we tag */
+      for(i=0;i<c->entries;i++){
+        if(c->lengthlist[i]==0){
+          oggpack_write(opb,0,1);
+        }else{
+          oggpack_write(opb,1,1);
+          oggpack_write(opb,c->lengthlist[i]-1,5);
+        }
+      }
+    }
+  }
+
+  /* is the entry number the desired return value, or do we have a
+     mapping? If we have a mapping, what type? */
+  oggpack_write(opb,c->maptype,4);
+  switch(c->maptype){
+  case 0:
+    /* no mapping */
+    break;
+  case 1:case 2:
+    /* implicitly populated value mapping */
+    /* explicitly populated value mapping */
+
+    if(!c->quantlist){
+      /* no quantlist?  error */
+      return(-1);
+    }
+
+    /* values that define the dequantization */
+    oggpack_write(opb,c->q_min,32);
+    oggpack_write(opb,c->q_delta,32);
+    oggpack_write(opb,c->q_quant-1,4);
+    oggpack_write(opb,c->q_sequencep,1);
+
+    {
+      int quantvals;
+      switch(c->maptype){
+      case 1:
+        /* a single column of (c->entries/c->dim) quantized values for
+           building a full value list algorithmically (square lattice) */
+        quantvals=_book_maptype1_quantvals(c);
+        break;
+      case 2:
+        /* every value (c->entries*c->dim total) specified explicitly */
+        quantvals=c->entries*c->dim;
+        break;
+      default: /* NOT_REACHABLE */
+        quantvals=-1;
+      }
+
+      /* quantized values */
+      for(i=0;i<quantvals;i++)
+        oggpack_write(opb,labs(c->quantlist[i]),c->q_quant);
+
+    }
+    break;
+  default:
+    /* error case; we don't have any other map types now */
+    return(-1);
+  }
+
+  return(0);
+}
+
+/* unpacks a codebook from the packet buffer into the codebook struct,
+   readies the codebook auxiliary structures for decode *************/
+static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
+  long i,j;
+  static_codebook *s=_ogg_calloc(1,sizeof(*s));
+  s->allocedp=1;
+
+  /* make sure alignment is correct */
+  if(oggpack_read(opb,24)!=0x564342)goto _eofout;
+
+  /* first the basic parameters */
+  s->dim=oggpack_read(opb,16);
+  s->entries=oggpack_read(opb,24);
+  if(s->entries==-1)goto _eofout;
+
+  if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout;
+
+  /* codeword ordering.... length ordered or unordered? */
+  switch((int)oggpack_read(opb,1)){
+  case 0:{
+    long unused;
+    /* allocated but unused entries? */
+    unused=oggpack_read(opb,1);
+    if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb))
+      goto _eofout;
+    /* unordered */
+    s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
+
+    /* allocated but unused entries? */
+    if(unused){
+      /* yes, unused entries */
+
+      for(i=0;i<s->entries;i++){
+        if(oggpack_read(opb,1)){
+          long num=oggpack_read(opb,5);
+          if(num==-1)goto _eofout;
+          s->lengthlist[i]=num+1;
+        }else
+          s->lengthlist[i]=0;
+      }
+    }else{
+      /* all entries used; no tagging */
+      for(i=0;i<s->entries;i++){
+        long num=oggpack_read(opb,5);
+        if(num==-1)goto _eofout;
+        s->lengthlist[i]=num+1;
+      }
+    }
+
+    break;
+  }
+  case 1:
+    /* ordered */
+    {
+      long length=oggpack_read(opb,5)+1;
+      if(length==0)goto _eofout;
+      s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
+
+      for(i=0;i<s->entries;){
+        long num=oggpack_read(opb,_ilog(s->entries-i));
+        if(num==-1)goto _eofout;
+        if(length>32 || num>s->entries-i ||
+           (num>0 && (num-1)>>(length-1)>1)){
+          goto _errout;
+        }
+        if(length>32)goto _errout;
+        for(j=0;j<num;j++,i++)
+          s->lengthlist[i]=length;
+        length++;
+      }
+    }
+    break;
+  default:
+    /* EOF */
+    goto _eofout;
+  }
+
+  /* Do we have a mapping to unpack? */
+  switch((s->maptype=oggpack_read(opb,4))){
+  case 0:
+    /* no mapping */
+    break;
+  case 1: case 2:
+    /* implicitly populated value mapping */
+    /* explicitly populated value mapping */
+
+    s->q_min=oggpack_read(opb,32);
+    s->q_delta=oggpack_read(opb,32);
+    s->q_quant=oggpack_read(opb,4)+1;
+    s->q_sequencep=oggpack_read(opb,1);
+    if(s->q_sequencep==-1)goto _eofout;
+
+    {
+      int quantvals=0;
+      switch(s->maptype){
+      case 1:
+        quantvals=(s->dim==0?0:_book_maptype1_quantvals(s));
+        break;
+      case 2:
+        quantvals=s->entries*s->dim;
+        break;
+      }
+
+      /* quantized values */
+      if(((quantvals*s->q_quant+7)>>3)>opb->storage-oggpack_bytes(opb))
+        goto _eofout;
+      s->quantlist=_ogg_malloc(sizeof(*s->quantlist)*quantvals);
+      for(i=0;i<quantvals;i++)
+        s->quantlist[i]=oggpack_read(opb,s->q_quant);
+
+      if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
+    }
+    break;
+  default:
+    goto _errout;
+  }
+
+  /* all set */
+  return(s);
+
+ _errout:
+ _eofout:
+  vorbis_staticbook_destroy(s);
+  return(NULL);
+}
+
+/* returns the number of bits ************************************************/
+int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){
+  if(a<0 || a>=book->c->entries)return(0);
+  oggpack_write(b,book->codelist[a],book->c->lengthlist[a]);
+  return(book->c->lengthlist[a]);
+}
+
+/* the 'eliminate the decode tree' optimization actually requires the
+   codewords to be MSb first, not LSb.  This is an annoying inelegancy
+   (and one of the first places where carefully thought out design
+   turned out to be wrong; Vorbis II and future Ogg codecs should go
+   to an MSb bitpacker), but not actually the huge hit it appears to
+   be.  The first-stage decode table catches most words so that
+   bitreverse is not in the main execution path. */
+
+static ogg_uint32_t bitreverse(ogg_uint32_t x){
+  x=    ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
+  x=    ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
+  x=    ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
+  x=    ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
+  return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
+}
+
+STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){
+  int  read=book->dec_maxlength;
+  long lo,hi;
+  long lok = oggpack_look(b,book->dec_firsttablen);
+
+  if (lok >= 0) {
+    long entry = book->dec_firsttable[lok];
+    if(entry&0x80000000UL){
+      lo=(entry>>15)&0x7fff;
+      hi=book->used_entries-(entry&0x7fff);
+    }else{
+      oggpack_adv(b, book->dec_codelengths[entry-1]);
+      return(entry-1);
+    }
+  }else{
+    lo=0;
+    hi=book->used_entries;
+  }
+
+  lok = oggpack_look(b, read);
+
+  while(lok<0 && read>1)
+    lok = oggpack_look(b, --read);
+  if(lok<0)return -1;
+
+  /* bisect search for the codeword in the ordered list */
+  {
+    ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
+
+    while(hi-lo>1){
+      long p=(hi-lo)>>1;
+      long test=book->codelist[lo+p]>testword;
+      lo+=p&(test-1);
+      hi-=p&(-test);
+      }
+
+    if(book->dec_codelengths[lo]<=read){
+      oggpack_adv(b, book->dec_codelengths[lo]);
+      return(lo);
+    }
+  }
+
+  oggpack_adv(b, read);
+
+  return(-1);
+}
+
+/* Decode side is specced and easier, because we don't need to find
+   matches using different criteria; we simply read and map.  There are
+   two things we need to do 'depending':
+
+   We may need to support interleave.  We don't really, but it's
+   convenient to do it here rather than rebuild the vector later.
+
+   Cascades may be additive or multiplicitive; this is not inherent in
+   the codebook, but set in the code using the codebook.  Like
+   interleaving, it's easiest to do it here.
+   addmul==0 -> declarative (set the value)
+   addmul==1 -> additive
+   addmul==2 -> multiplicitive */
+
+/* returns the [original, not compacted] entry number or -1 on eof *********/
+long vorbis_book_decode(codebook *book, oggpack_buffer *b){
+  if(book->used_entries>0){
+    long packed_entry=decode_packed_entry_number(book,b);
+    if(packed_entry>=0)
+      return(book->dec_index[packed_entry]);
+  }
+
+  /* if there's no dec_index, the codebook unpacking isn't collapsed */
+  return(-1);
+}
+
+/* returns 0 on OK or -1 on eof *************************************/
+/* decode vector / dim granularity gaurding is done in the upper layer */
+long vorbis_book_decodevs_add(codebook *book,float *a,oggpack_buffer *b,int n){
+  if(book->used_entries>0){
+    int step=n/book->dim;
+    long *entry = alloca(sizeof(*entry)*step);
+    float **t = alloca(sizeof(*t)*step);
+    int i,j,o;
+
+    for (i = 0; i < step; i++) {
+      entry[i]=decode_packed_entry_number(book,b);
+      if(entry[i]==-1)return(-1);
+      t[i] = book->valuelist+entry[i]*book->dim;
+    }
+    for(i=0,o=0;i<book->dim;i++,o+=step)
+      for (j=0;j<step;j++)
+        a[o+j]+=t[j][i];
+  }
+  return(0);
+}
+
+/* decode vector / dim granularity gaurding is done in the upper layer */
+long vorbis_book_decodev_add(codebook *book,float *a,oggpack_buffer *b,int n){
+  if(book->used_entries>0){
+    int i,j,entry;
+    float *t;
+
+    if(book->dim>8){
+      for(i=0;i<n;){
+        entry = decode_packed_entry_number(book,b);
+        if(entry==-1)return(-1);
+        t     = book->valuelist+entry*book->dim;
+        for (j=0;j<book->dim;)
+          a[i++]+=t[j++];
+      }
+    }else{
+      for(i=0;i<n;){
+        entry = decode_packed_entry_number(book,b);
+        if(entry==-1)return(-1);
+        t     = book->valuelist+entry*book->dim;
+        j=0;
+        switch((int)book->dim){
+        case 8:
+          a[i++]+=t[j++];
+        case 7:
+          a[i++]+=t[j++];
+        case 6:
+          a[i++]+=t[j++];
+        case 5:
+          a[i++]+=t[j++];
+        case 4:
+          a[i++]+=t[j++];
+        case 3:
+          a[i++]+=t[j++];
+        case 2:
+          a[i++]+=t[j++];
+        case 1:
+          a[i++]+=t[j++];
+        case 0:
+          break;
+        }
+      }
+    }
+  }
+  return(0);
+}
+
+/* unlike the others, we guard against n not being an integer number
+   of <dim> internally rather than in the upper layer (called only by
+   floor0) */
+long vorbis_book_decodev_set(codebook *book,float *a,oggpack_buffer *b,int n){
+  if(book->used_entries>0){
+    int i,j,entry;
+    float *t;
+
+    for(i=0;i<n;){
+      entry = decode_packed_entry_number(book,b);
+      if(entry==-1)return(-1);
+      t     = book->valuelist+entry*book->dim;
+      for (j=0;i<n && j<book->dim;){
+        a[i++]=t[j++];
+      }
+    }
+  }else{
+    int i;
+
+    for(i=0;i<n;){
+      a[i++]=0.f;
+    }
+  }
+  return(0);
+}
+
+long vorbis_book_decodevv_add(codebook *book,float **a,long offset,int ch,
+                              oggpack_buffer *b,int n){
+
+  long i,j,entry;
+  int chptr=0;
+  if(book->used_entries>0){
+    for(i=offset/ch;i<(offset+n)/ch;){
+      entry = decode_packed_entry_number(book,b);
+      if(entry==-1)return(-1);
+      {
+        const float *t = book->valuelist+entry*book->dim;
+        for (j=0;j<book->dim;j++){
+          a[chptr++][i]+=t[j];
+          if(chptr==ch){
+            chptr=0;
+            i++;
+          }
+        }
+      }
+    }
+  }
+  return(0);
+}

+ 119 - 0
liboggvorbis/src/codebook.h

@@ -0,0 +1,119 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2014             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: basic shared codebook operations
+ last mod: $Id: codebook.h 19057 2014-01-22 12:32:31Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _V_CODEBOOK_H_
+#define _V_CODEBOOK_H_
+
+#include <ogg/ogg.h>
+
+/* This structure encapsulates huffman and VQ style encoding books; it
+   doesn't do anything specific to either.
+
+   valuelist/quantlist are nonNULL (and q_* significant) only if
+   there's entry->value mapping to be done.
+
+   If encode-side mapping must be done (and thus the entry needs to be
+   hunted), the auxiliary encode pointer will point to a decision
+   tree.  This is true of both VQ and huffman, but is mostly useful
+   with VQ.
+
+*/
+
+typedef struct static_codebook{
+  long   dim;           /* codebook dimensions (elements per vector) */
+  long   entries;       /* codebook entries */
+  char  *lengthlist;    /* codeword lengths in bits */
+
+  /* mapping ***************************************************************/
+  int    maptype;       /* 0=none
+                           1=implicitly populated values from map column
+                           2=listed arbitrary values */
+
+  /* The below does a linear, single monotonic sequence mapping. */
+  long     q_min;       /* packed 32 bit float; quant value 0 maps to minval */
+  long     q_delta;     /* packed 32 bit float; val 1 - val 0 == delta */
+  int      q_quant;     /* bits: 0 < quant <= 16 */
+  int      q_sequencep; /* bitflag */
+
+  long     *quantlist;  /* map == 1: (int)(entries^(1/dim)) element column map
+                           map == 2: list of dim*entries quantized entry vals
+                        */
+  int allocedp;
+} static_codebook;
+
+typedef struct codebook{
+  long dim;           /* codebook dimensions (elements per vector) */
+  long entries;       /* codebook entries */
+  long used_entries;  /* populated codebook entries */
+  const static_codebook *c;
+
+  /* for encode, the below are entry-ordered, fully populated */
+  /* for decode, the below are ordered by bitreversed codeword and only
+     used entries are populated */
+  float        *valuelist;  /* list of dim*entries actual entry values */
+  ogg_uint32_t *codelist;   /* list of bitstream codewords for each entry */
+
+  int          *dec_index;  /* only used if sparseness collapsed */
+  char         *dec_codelengths;
+  ogg_uint32_t *dec_firsttable;
+  int           dec_firsttablen;
+  int           dec_maxlength;
+
+  /* The current encoder uses only centered, integer-only lattice books. */
+  int           quantvals;
+  int           minval;
+  int           delta;
+} codebook;
+
+extern void vorbis_staticbook_destroy(static_codebook *b);
+extern int vorbis_book_init_encode(codebook *dest,const static_codebook *source);
+extern int vorbis_book_init_decode(codebook *dest,const static_codebook *source);
+extern void vorbis_book_clear(codebook *b);
+
+extern float *_book_unquantize(const static_codebook *b,int n,int *map);
+extern float *_book_logdist(const static_codebook *b,float *vals);
+extern float _float32_unpack(long val);
+extern long   _float32_pack(float val);
+extern int  _best(codebook *book, float *a, int step);
+extern int _ilog(unsigned int v);
+extern long _book_maptype1_quantvals(const static_codebook *b);
+
+extern int vorbis_book_besterror(codebook *book,float *a,int step,int addmul);
+extern long vorbis_book_codeword(codebook *book,int entry);
+extern long vorbis_book_codelen(codebook *book,int entry);
+
+
+
+extern int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *b);
+extern static_codebook *vorbis_staticbook_unpack(oggpack_buffer *b);
+
+extern int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b);
+
+extern long vorbis_book_decode(codebook *book, oggpack_buffer *b);
+extern long vorbis_book_decodevs_add(codebook *book, float *a,
+                                     oggpack_buffer *b,int n);
+extern long vorbis_book_decodev_set(codebook *book, float *a,
+                                    oggpack_buffer *b,int n);
+extern long vorbis_book_decodev_add(codebook *book, float *a,
+                                    oggpack_buffer *b,int n);
+extern long vorbis_book_decodevv_add(codebook *book, float **a,
+                                     long off,int ch,
+                                    oggpack_buffer *b,int n);
+
+
+
+#endif

+ 167 - 0
liboggvorbis/src/codec_internal.h

@@ -0,0 +1,167 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: libvorbis codec headers
+ last mod: $Id: codec_internal.h 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _V_CODECI_H_
+#define _V_CODECI_H_
+
+#include "envelope.h"
+#include "codebook.h"
+
+#define BLOCKTYPE_IMPULSE    0
+#define BLOCKTYPE_PADDING    1
+#define BLOCKTYPE_TRANSITION 0
+#define BLOCKTYPE_LONG       1
+
+#define PACKETBLOBS 15
+
+typedef struct vorbis_block_internal{
+  float  **pcmdelay;  /* this is a pointer into local storage */
+  float  ampmax;
+  int    blocktype;
+
+  oggpack_buffer *packetblob[PACKETBLOBS]; /* initialized, must be freed;
+                                              blob [PACKETBLOBS/2] points to
+                                              the oggpack_buffer in the
+                                              main vorbis_block */
+} vorbis_block_internal;
+
+typedef void vorbis_look_floor;
+typedef void vorbis_look_residue;
+typedef void vorbis_look_transform;
+
+/* mode ************************************************************/
+typedef struct {
+  int blockflag;
+  int windowtype;
+  int transformtype;
+  int mapping;
+} vorbis_info_mode;
+
+typedef void vorbis_info_floor;
+typedef void vorbis_info_residue;
+typedef void vorbis_info_mapping;
+
+#include "psy.h"
+#include "bitrate.h"
+
+typedef struct private_state {
+  /* local lookup storage */
+  envelope_lookup        *ve; /* envelope lookup */
+  int                     window[2];
+  vorbis_look_transform **transform[2];    /* block, type */
+  drft_lookup             fft_look[2];
+
+  int                     modebits;
+  vorbis_look_floor     **flr;
+  vorbis_look_residue   **residue;
+  vorbis_look_psy        *psy;
+  vorbis_look_psy_global *psy_g_look;
+
+  /* local storage, only used on the encoding side.  This way the
+     application does not need to worry about freeing some packets'
+     memory and not others'; packet storage is always tracked.
+     Cleared next call to a _dsp_ function */
+  unsigned char *header;
+  unsigned char *header1;
+  unsigned char *header2;
+
+  bitrate_manager_state bms;
+
+  ogg_int64_t sample_count;
+} private_state;
+
+/* codec_setup_info contains all the setup information specific to the
+   specific compression/decompression mode in progress (eg,
+   psychoacoustic settings, channel setup, options, codebook
+   etc).
+*********************************************************************/
+
+#include "highlevel.h"
+typedef struct codec_setup_info {
+
+  /* Vorbis supports only short and long blocks, but allows the
+     encoder to choose the sizes */
+
+  long blocksizes[2];
+
+  /* modes are the primary means of supporting on-the-fly different
+     blocksizes, different channel mappings (LR or M/A),
+     different residue backends, etc.  Each mode consists of a
+     blocksize flag and a mapping (along with the mapping setup */
+
+  int        modes;
+  int        maps;
+  int        floors;
+  int        residues;
+  int        books;
+  int        psys;     /* encode only */
+
+  vorbis_info_mode       *mode_param[64];
+  int                     map_type[64];
+  vorbis_info_mapping    *map_param[64];
+  int                     floor_type[64];
+  vorbis_info_floor      *floor_param[64];
+  int                     residue_type[64];
+  vorbis_info_residue    *residue_param[64];
+  static_codebook        *book_param[256];
+  codebook               *fullbooks;
+
+  vorbis_info_psy        *psy_param[4]; /* encode only */
+  vorbis_info_psy_global psy_g_param;
+
+  bitrate_manager_info   bi;
+  highlevel_encode_setup hi; /* used only by vorbisenc.c.  It's a
+                                highly redundant structure, but
+                                improves clarity of program flow. */
+  int         halfrate_flag; /* painless downsample for decode */
+} codec_setup_info;
+
+extern vorbis_look_psy_global *_vp_global_look(vorbis_info *vi);
+extern void _vp_global_free(vorbis_look_psy_global *look);
+
+
+
+typedef struct {
+  int sorted_index[VIF_POSIT+2];
+  int forward_index[VIF_POSIT+2];
+  int reverse_index[VIF_POSIT+2];
+
+  int hineighbor[VIF_POSIT];
+  int loneighbor[VIF_POSIT];
+  int posts;
+
+  int n;
+  int quant_q;
+  vorbis_info_floor1 *vi;
+
+  long phrasebits;
+  long postbits;
+  long frames;
+} vorbis_look_floor1;
+
+
+
+extern int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look,
+                          const float *logmdct,   /* in */
+                          const float *logmask);
+extern int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look,
+                          int *A,int *B,
+                          int del);
+extern int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
+                  vorbis_look_floor1 *look,
+                  int *post,int *ilogmask);
+#endif

+ 375 - 0
liboggvorbis/src/envelope.c

@@ -0,0 +1,375 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: PCM data envelope analysis
+ last mod: $Id: envelope.c 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+
+#include "os.h"
+#include "scales.h"
+#include "envelope.h"
+#include "mdct.h"
+#include "misc.h"
+
+void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){
+  codec_setup_info *ci=vi->codec_setup;
+  vorbis_info_psy_global *gi=&ci->psy_g_param;
+  int ch=vi->channels;
+  int i,j;
+  int n=e->winlength=128;
+  e->searchstep=64; /* not random */
+
+  e->minenergy=gi->preecho_minenergy;
+  e->ch=ch;
+  e->storage=128;
+  e->cursor=ci->blocksizes[1]/2;
+  e->mdct_win=_ogg_calloc(n,sizeof(*e->mdct_win));
+  mdct_init(&e->mdct,n);
+
+  for(i=0;i<n;i++){
+    e->mdct_win[i]=sin(i/(n-1.)*M_PI);
+    e->mdct_win[i]*=e->mdct_win[i];
+  }
+
+  /* magic follows */
+  e->band[0].begin=2;  e->band[0].end=4;
+  e->band[1].begin=4;  e->band[1].end=5;
+  e->band[2].begin=6;  e->band[2].end=6;
+  e->band[3].begin=9;  e->band[3].end=8;
+  e->band[4].begin=13;  e->band[4].end=8;
+  e->band[5].begin=17;  e->band[5].end=8;
+  e->band[6].begin=22;  e->band[6].end=8;
+
+  for(j=0;j<VE_BANDS;j++){
+    n=e->band[j].end;
+    e->band[j].window=_ogg_malloc(n*sizeof(*e->band[0].window));
+    for(i=0;i<n;i++){
+      e->band[j].window[i]=sin((i+.5)/n*M_PI);
+      e->band[j].total+=e->band[j].window[i];
+    }
+    e->band[j].total=1./e->band[j].total;
+  }
+
+  e->filter=_ogg_calloc(VE_BANDS*ch,sizeof(*e->filter));
+  e->mark=_ogg_calloc(e->storage,sizeof(*e->mark));
+
+}
+
+void _ve_envelope_clear(envelope_lookup *e){
+  int i;
+  mdct_clear(&e->mdct);
+  for(i=0;i<VE_BANDS;i++)
+    _ogg_free(e->band[i].window);
+  _ogg_free(e->mdct_win);
+  _ogg_free(e->filter);
+  _ogg_free(e->mark);
+  memset(e,0,sizeof(*e));
+}
+
+/* fairly straight threshhold-by-band based until we find something
+   that works better and isn't patented. */
+
+static int _ve_amp(envelope_lookup *ve,
+                   vorbis_info_psy_global *gi,
+                   float *data,
+                   envelope_band *bands,
+                   envelope_filter_state *filters){
+  long n=ve->winlength;
+  int ret=0;
+  long i,j;
+  float decay;
+
+  /* we want to have a 'minimum bar' for energy, else we're just
+     basing blocks on quantization noise that outweighs the signal
+     itself (for low power signals) */
+
+  float minV=ve->minenergy;
+  float *vec=alloca(n*sizeof(*vec));
+
+  /* stretch is used to gradually lengthen the number of windows
+     considered prevoius-to-potential-trigger */
+  int stretch=max(VE_MINSTRETCH,ve->stretch/2);
+  float penalty=gi->stretch_penalty-(ve->stretch/2-VE_MINSTRETCH);
+  if(penalty<0.f)penalty=0.f;
+  if(penalty>gi->stretch_penalty)penalty=gi->stretch_penalty;
+
+  /*_analysis_output_always("lpcm",seq2,data,n,0,0,
+    totalshift+pos*ve->searchstep);*/
+
+ /* window and transform */
+  for(i=0;i<n;i++)
+    vec[i]=data[i]*ve->mdct_win[i];
+  mdct_forward(&ve->mdct,vec,vec);
+
+  /*_analysis_output_always("mdct",seq2,vec,n/2,0,1,0); */
+
+  /* near-DC spreading function; this has nothing to do with
+     psychoacoustics, just sidelobe leakage and window size */
+  {
+    float temp=vec[0]*vec[0]+.7*vec[1]*vec[1]+.2*vec[2]*vec[2];
+    int ptr=filters->nearptr;
+
+    /* the accumulation is regularly refreshed from scratch to avoid
+       floating point creep */
+    if(ptr==0){
+      decay=filters->nearDC_acc=filters->nearDC_partialacc+temp;
+      filters->nearDC_partialacc=temp;
+    }else{
+      decay=filters->nearDC_acc+=temp;
+      filters->nearDC_partialacc+=temp;
+    }
+    filters->nearDC_acc-=filters->nearDC[ptr];
+    filters->nearDC[ptr]=temp;
+
+    decay*=(1./(VE_NEARDC+1));
+    filters->nearptr++;
+    if(filters->nearptr>=VE_NEARDC)filters->nearptr=0;
+    decay=todB(&decay)*.5-15.f;
+  }
+
+  /* perform spreading and limiting, also smooth the spectrum.  yes,
+     the MDCT results in all real coefficients, but it still *behaves*
+     like real/imaginary pairs */
+  for(i=0;i<n/2;i+=2){
+    float val=vec[i]*vec[i]+vec[i+1]*vec[i+1];
+    val=todB(&val)*.5f;
+    if(val<decay)val=decay;
+    if(val<minV)val=minV;
+    vec[i>>1]=val;
+    decay-=8.;
+  }
+
+  /*_analysis_output_always("spread",seq2++,vec,n/4,0,0,0);*/
+
+  /* perform preecho/postecho triggering by band */
+  for(j=0;j<VE_BANDS;j++){
+    float acc=0.;
+    float valmax,valmin;
+
+    /* accumulate amplitude */
+    for(i=0;i<bands[j].end;i++)
+      acc+=vec[i+bands[j].begin]*bands[j].window[i];
+
+    acc*=bands[j].total;
+
+    /* convert amplitude to delta */
+    {
+      int p,this=filters[j].ampptr;
+      float postmax,postmin,premax=-99999.f,premin=99999.f;
+
+      p=this;
+      p--;
+      if(p<0)p+=VE_AMP;
+      postmax=max(acc,filters[j].ampbuf[p]);
+      postmin=min(acc,filters[j].ampbuf[p]);
+
+      for(i=0;i<stretch;i++){
+        p--;
+        if(p<0)p+=VE_AMP;
+        premax=max(premax,filters[j].ampbuf[p]);
+        premin=min(premin,filters[j].ampbuf[p]);
+      }
+
+      valmin=postmin-premin;
+      valmax=postmax-premax;
+
+      /*filters[j].markers[pos]=valmax;*/
+      filters[j].ampbuf[this]=acc;
+      filters[j].ampptr++;
+      if(filters[j].ampptr>=VE_AMP)filters[j].ampptr=0;
+    }
+
+    /* look at min/max, decide trigger */
+    if(valmax>gi->preecho_thresh[j]+penalty){
+      ret|=1;
+      ret|=4;
+    }
+    if(valmin<gi->postecho_thresh[j]-penalty)ret|=2;
+  }
+
+  return(ret);
+}
+
+#if 0
+static int seq=0;
+static ogg_int64_t totalshift=-1024;
+#endif
+
+long _ve_envelope_search(vorbis_dsp_state *v){
+  vorbis_info *vi=v->vi;
+  codec_setup_info *ci=vi->codec_setup;
+  vorbis_info_psy_global *gi=&ci->psy_g_param;
+  envelope_lookup *ve=((private_state *)(v->backend_state))->ve;
+  long i,j;
+
+  int first=ve->current/ve->searchstep;
+  int last=v->pcm_current/ve->searchstep-VE_WIN;
+  if(first<0)first=0;
+
+  /* make sure we have enough storage to match the PCM */
+  if(last+VE_WIN+VE_POST>ve->storage){
+    ve->storage=last+VE_WIN+VE_POST; /* be sure */
+    ve->mark=_ogg_realloc(ve->mark,ve->storage*sizeof(*ve->mark));
+  }
+
+  for(j=first;j<last;j++){
+    int ret=0;
+
+    ve->stretch++;
+    if(ve->stretch>VE_MAXSTRETCH*2)
+      ve->stretch=VE_MAXSTRETCH*2;
+
+    for(i=0;i<ve->ch;i++){
+      float *pcm=v->pcm[i]+ve->searchstep*(j);
+      ret|=_ve_amp(ve,gi,pcm,ve->band,ve->filter+i*VE_BANDS);
+    }
+
+    ve->mark[j+VE_POST]=0;
+    if(ret&1){
+      ve->mark[j]=1;
+      ve->mark[j+1]=1;
+    }
+
+    if(ret&2){
+      ve->mark[j]=1;
+      if(j>0)ve->mark[j-1]=1;
+    }
+
+    if(ret&4)ve->stretch=-1;
+  }
+
+  ve->current=last*ve->searchstep;
+
+  {
+    long centerW=v->centerW;
+    long testW=
+      centerW+
+      ci->blocksizes[v->W]/4+
+      ci->blocksizes[1]/2+
+      ci->blocksizes[0]/4;
+
+    j=ve->cursor;
+
+    while(j<ve->current-(ve->searchstep)){/* account for postecho
+                                             working back one window */
+      if(j>=testW)return(1);
+
+      ve->cursor=j;
+
+      if(ve->mark[j/ve->searchstep]){
+        if(j>centerW){
+
+#if 0
+          if(j>ve->curmark){
+            float *marker=alloca(v->pcm_current*sizeof(*marker));
+            int l,m;
+            memset(marker,0,sizeof(*marker)*v->pcm_current);
+            fprintf(stderr,"mark! seq=%d, cursor:%fs time:%fs\n",
+                    seq,
+                    (totalshift+ve->cursor)/44100.,
+                    (totalshift+j)/44100.);
+            _analysis_output_always("pcmL",seq,v->pcm[0],v->pcm_current,0,0,totalshift);
+            _analysis_output_always("pcmR",seq,v->pcm[1],v->pcm_current,0,0,totalshift);
+
+            _analysis_output_always("markL",seq,v->pcm[0],j,0,0,totalshift);
+            _analysis_output_always("markR",seq,v->pcm[1],j,0,0,totalshift);
+
+            for(m=0;m<VE_BANDS;m++){
+              char buf[80];
+              sprintf(buf,"delL%d",m);
+              for(l=0;l<last;l++)marker[l*ve->searchstep]=ve->filter[m].markers[l]*.1;
+              _analysis_output_always(buf,seq,marker,v->pcm_current,0,0,totalshift);
+            }
+
+            for(m=0;m<VE_BANDS;m++){
+              char buf[80];
+              sprintf(buf,"delR%d",m);
+              for(l=0;l<last;l++)marker[l*ve->searchstep]=ve->filter[m+VE_BANDS].markers[l]*.1;
+              _analysis_output_always(buf,seq,marker,v->pcm_current,0,0,totalshift);
+            }
+
+            for(l=0;l<last;l++)marker[l*ve->searchstep]=ve->mark[l]*.4;
+            _analysis_output_always("mark",seq,marker,v->pcm_current,0,0,totalshift);
+
+
+            seq++;
+
+          }
+#endif
+
+          ve->curmark=j;
+          if(j>=testW)return(1);
+          return(0);
+        }
+      }
+      j+=ve->searchstep;
+    }
+  }
+
+  return(-1);
+}
+
+int _ve_envelope_mark(vorbis_dsp_state *v){
+  envelope_lookup *ve=((private_state *)(v->backend_state))->ve;
+  vorbis_info *vi=v->vi;
+  codec_setup_info *ci=vi->codec_setup;
+  long centerW=v->centerW;
+  long beginW=centerW-ci->blocksizes[v->W]/4;
+  long endW=centerW+ci->blocksizes[v->W]/4;
+  if(v->W){
+    beginW-=ci->blocksizes[v->lW]/4;
+    endW+=ci->blocksizes[v->nW]/4;
+  }else{
+    beginW-=ci->blocksizes[0]/4;
+    endW+=ci->blocksizes[0]/4;
+  }
+
+  if(ve->curmark>=beginW && ve->curmark<endW)return(1);
+  {
+    long first=beginW/ve->searchstep;
+    long last=endW/ve->searchstep;
+    long i;
+    for(i=first;i<last;i++)
+      if(ve->mark[i])return(1);
+  }
+  return(0);
+}
+
+void _ve_envelope_shift(envelope_lookup *e,long shift){
+  int smallsize=e->current/e->searchstep+VE_POST; /* adjust for placing marks
+                                                     ahead of ve->current */
+  int smallshift=shift/e->searchstep;
+
+  memmove(e->mark,e->mark+smallshift,(smallsize-smallshift)*sizeof(*e->mark));
+
+#if 0
+  for(i=0;i<VE_BANDS*e->ch;i++)
+    memmove(e->filter[i].markers,
+            e->filter[i].markers+smallshift,
+            (1024-smallshift)*sizeof(*(*e->filter).markers));
+  totalshift+=shift;
+#endif
+
+  e->current-=shift;
+  if(e->curmark>=0)
+    e->curmark-=shift;
+  e->cursor-=shift;
+}

+ 80 - 0
liboggvorbis/src/envelope.h

@@ -0,0 +1,80 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: PCM data envelope analysis and manipulation
+ last mod: $Id: envelope.h 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _V_ENVELOPE_
+#define _V_ENVELOPE_
+
+#include "mdct.h"
+
+#define VE_PRE    16
+#define VE_WIN    4
+#define VE_POST   2
+#define VE_AMP    (VE_PRE+VE_POST-1)
+
+#define VE_BANDS  7
+#define VE_NEARDC 15
+
+#define VE_MINSTRETCH 2   /* a bit less than short block */
+#define VE_MAXSTRETCH 12  /* one-third full block */
+
+typedef struct {
+  float ampbuf[VE_AMP];
+  int   ampptr;
+
+  float nearDC[VE_NEARDC];
+  float nearDC_acc;
+  float nearDC_partialacc;
+  int   nearptr;
+
+} envelope_filter_state;
+
+typedef struct {
+  int begin;
+  int end;
+  float *window;
+  float total;
+} envelope_band;
+
+typedef struct {
+  int ch;
+  int winlength;
+  int searchstep;
+  float minenergy;
+
+  mdct_lookup  mdct;
+  float       *mdct_win;
+
+  envelope_band          band[VE_BANDS];
+  envelope_filter_state *filter;
+  int   stretch;
+
+  int                   *mark;
+
+  long storage;
+  long current;
+  long curmark;
+  long cursor;
+} envelope_lookup;
+
+extern void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi);
+extern void _ve_envelope_clear(envelope_lookup *e);
+extern long _ve_envelope_search(vorbis_dsp_state *v);
+extern void _ve_envelope_shift(envelope_lookup *e,long shift);
+extern int  _ve_envelope_mark(vorbis_dsp_state *v);
+
+
+#endif

+ 224 - 0
liboggvorbis/src/floor0.c

@@ -0,0 +1,224 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: floor backend 0 implementation
+ last mod: $Id: floor0.c 19031 2013-12-03 19:20:50Z tterribe $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+#include "registry.h"
+#include "lpc.h"
+#include "lsp.h"
+#include "codebook.h"
+#include "scales.h"
+#include "misc.h"
+#include "os.h"
+
+#include "misc.h"
+#include <stdio.h>
+
+typedef struct {
+  int ln;
+  int  m;
+  int **linearmap;
+  int  n[2];
+
+  vorbis_info_floor0 *vi;
+
+  long bits;
+  long frames;
+} vorbis_look_floor0;
+
+
+/***********************************************/
+
+static void floor0_free_info(vorbis_info_floor *i){
+  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
+  if(info){
+    memset(info,0,sizeof(*info));
+    _ogg_free(info);
+  }
+}
+
+static void floor0_free_look(vorbis_look_floor *i){
+  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
+  if(look){
+
+    if(look->linearmap){
+
+      if(look->linearmap[0])_ogg_free(look->linearmap[0]);
+      if(look->linearmap[1])_ogg_free(look->linearmap[1]);
+
+      _ogg_free(look->linearmap);
+    }
+    memset(look,0,sizeof(*look));
+    _ogg_free(look);
+  }
+}
+
+static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
+  codec_setup_info     *ci=vi->codec_setup;
+  int j;
+
+  vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info));
+  info->order=oggpack_read(opb,8);
+  info->rate=oggpack_read(opb,16);
+  info->barkmap=oggpack_read(opb,16);
+  info->ampbits=oggpack_read(opb,6);
+  info->ampdB=oggpack_read(opb,8);
+  info->numbooks=oggpack_read(opb,4)+1;
+
+  if(info->order<1)goto err_out;
+  if(info->rate<1)goto err_out;
+  if(info->barkmap<1)goto err_out;
+  if(info->numbooks<1)goto err_out;
+
+  for(j=0;j<info->numbooks;j++){
+    info->books[j]=oggpack_read(opb,8);
+    if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
+    if(ci->book_param[info->books[j]]->maptype==0)goto err_out;
+    if(ci->book_param[info->books[j]]->dim<1)goto err_out;
+  }
+  return(info);
+
+ err_out:
+  floor0_free_info(info);
+  return(NULL);
+}
+
+/* initialize Bark scale and normalization lookups.  We could do this
+   with static tables, but Vorbis allows a number of possible
+   combinations, so it's best to do it computationally.
+
+   The below is authoritative in terms of defining scale mapping.
+   Note that the scale depends on the sampling rate as well as the
+   linear block and mapping sizes */
+
+static void floor0_map_lazy_init(vorbis_block      *vb,
+                                 vorbis_info_floor *infoX,
+                                 vorbis_look_floor0 *look){
+  if(!look->linearmap[vb->W]){
+    vorbis_dsp_state   *vd=vb->vd;
+    vorbis_info        *vi=vd->vi;
+    codec_setup_info   *ci=vi->codec_setup;
+    vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX;
+    int W=vb->W;
+    int n=ci->blocksizes[W]/2,j;
+
+    /* we choose a scaling constant so that:
+       floor(bark(rate/2-1)*C)=mapped-1
+     floor(bark(rate/2)*C)=mapped */
+    float scale=look->ln/toBARK(info->rate/2.f);
+
+    /* the mapping from a linear scale to a smaller bark scale is
+       straightforward.  We do *not* make sure that the linear mapping
+       does not skip bark-scale bins; the decoder simply skips them and
+       the encoder may do what it wishes in filling them.  They're
+       necessary in some mapping combinations to keep the scale spacing
+       accurate */
+    look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap));
+    for(j=0;j<n;j++){
+      int val=floor( toBARK((info->rate/2.f)/n*j)
+                     *scale); /* bark numbers represent band edges */
+      if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
+      look->linearmap[W][j]=val;
+    }
+    look->linearmap[W][j]=-1;
+    look->n[W]=n;
+  }
+}
+
+static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd,
+                                      vorbis_info_floor *i){
+  vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
+  vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look));
+
+  (void)vd;
+
+  look->m=info->order;
+  look->ln=info->barkmap;
+  look->vi=info;
+
+  look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap));
+
+  return look;
+}
+
+static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
+  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
+  vorbis_info_floor0 *info=look->vi;
+  int j,k;
+
+  int ampraw=oggpack_read(&vb->opb,info->ampbits);
+  if(ampraw>0){ /* also handles the -1 out of data case */
+    long maxval=(1<<info->ampbits)-1;
+    float amp=(float)ampraw/maxval*info->ampdB;
+    int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
+
+    if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
+      codec_setup_info  *ci=vb->vd->vi->codec_setup;
+      codebook *b=ci->fullbooks+info->books[booknum];
+      float last=0.f;
+
+      /* the additional b->dim is a guard against any possible stack
+         smash; b->dim is provably more than we can overflow the
+         vector */
+      float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1));
+
+      if(vorbis_book_decodev_set(b,lsp,&vb->opb,look->m)==-1)goto eop;
+      for(j=0;j<look->m;){
+        for(k=0;j<look->m && k<b->dim;k++,j++)lsp[j]+=last;
+        last=lsp[j-1];
+      }
+
+      lsp[look->m]=amp;
+      return(lsp);
+    }
+  }
+ eop:
+  return(NULL);
+}
+
+static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
+                           void *memo,float *out){
+  vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
+  vorbis_info_floor0 *info=look->vi;
+
+  floor0_map_lazy_init(vb,info,look);
+
+  if(memo){
+    float *lsp=(float *)memo;
+    float amp=lsp[look->m];
+
+    /* take the coefficients back to a spectral envelope curve */
+    vorbis_lsp_to_curve(out,
+                        look->linearmap[vb->W],
+                        look->n[vb->W],
+                        look->ln,
+                        lsp,look->m,amp,(float)info->ampdB);
+    return(1);
+  }
+  memset(out,0,sizeof(*out)*look->n[vb->W]);
+  return(0);
+}
+
+/* export hooks */
+const vorbis_func_floor floor0_exportbundle={
+  NULL,&floor0_unpack,&floor0_look,&floor0_free_info,
+  &floor0_free_look,&floor0_inverse1,&floor0_inverse2
+};

File diff suppressed because it is too large
+ 1102 - 0
liboggvorbis/src/floor1.c


File diff suppressed because it is too large
+ 2111 - 0
liboggvorbis/src/framing.c


+ 58 - 0
liboggvorbis/src/highlevel.h

@@ -0,0 +1,58 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: highlevel encoder setup struct separated out for vorbisenc clarity
+ last mod: $Id: highlevel.h 17195 2010-05-05 21:49:51Z giles $
+
+ ********************************************************************/
+
+typedef struct highlevel_byblocktype {
+  double tone_mask_setting;
+  double tone_peaklimit_setting;
+  double noise_bias_setting;
+  double noise_compand_setting;
+} highlevel_byblocktype;
+
+typedef struct highlevel_encode_setup {
+  int   set_in_stone;
+  const void *setup;
+  double base_setting;
+
+  double impulse_noisetune;
+
+  /* bitrate management below all settable */
+  float  req;
+  int    managed;
+  long   bitrate_min;
+  long   bitrate_av;
+  double bitrate_av_damp;
+  long   bitrate_max;
+  long   bitrate_reservoir;
+  double bitrate_reservoir_bias;
+
+  int impulse_block_p;
+  int noise_normalize_p;
+  int coupling_p;
+
+  double stereo_point_setting;
+  double lowpass_kHz;
+  int    lowpass_altered;
+
+  double ath_floating_dB;
+  double ath_absolute_dB;
+
+  double amplitude_track_dBpersec;
+  double trigger_setting;
+
+  highlevel_byblocktype block[4]; /* padding, impulse, transition, long */
+
+} highlevel_encode_setup;

+ 668 - 0
liboggvorbis/src/info.c

@@ -0,0 +1,668 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: maintain the info structure, info <-> header packets
+ last mod: $Id: info.c 19058 2014-01-22 18:03:15Z xiphmont $
+
+ ********************************************************************/
+
+/* general handling of the header and the vorbis_info structure (and
+   substructures) */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+#include "codebook.h"
+#include "registry.h"
+#include "window.h"
+#include "psy.h"
+#include "misc.h"
+#include "os.h"
+
+#define GENERAL_VENDOR_STRING "Xiph.Org libVorbis 1.3.4"
+#define ENCODE_VENDOR_STRING "Xiph.Org libVorbis I 20140122 (Turpakäräjiin)"
+
+/* helpers */
+static int ilog2(unsigned int v){
+  int ret=0;
+  if(v)--v;
+  while(v){
+    ret++;
+    v>>=1;
+  }
+  return(ret);
+}
+
+static void _v_writestring(oggpack_buffer *o,const char *s, int bytes){
+
+  while(bytes--){
+    oggpack_write(o,*s++,8);
+  }
+}
+
+static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
+  while(bytes--){
+    *buf++=oggpack_read(o,8);
+  }
+}
+
+void vorbis_comment_init(vorbis_comment *vc){
+  memset(vc,0,sizeof(*vc));
+}
+
+void vorbis_comment_add(vorbis_comment *vc,const char *comment){
+  vc->user_comments=_ogg_realloc(vc->user_comments,
+                            (vc->comments+2)*sizeof(*vc->user_comments));
+  vc->comment_lengths=_ogg_realloc(vc->comment_lengths,
+                                  (vc->comments+2)*sizeof(*vc->comment_lengths));
+  vc->comment_lengths[vc->comments]=strlen(comment);
+  vc->user_comments[vc->comments]=_ogg_malloc(vc->comment_lengths[vc->comments]+1);
+  strcpy(vc->user_comments[vc->comments], comment);
+  vc->comments++;
+  vc->user_comments[vc->comments]=NULL;
+}
+
+void vorbis_comment_add_tag(vorbis_comment *vc, const char *tag, const char *contents){
+  char *comment=alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */
+  strcpy(comment, tag);
+  strcat(comment, "=");
+  strcat(comment, contents);
+  vorbis_comment_add(vc, comment);
+}
+
+/* This is more or less the same as strncasecmp - but that doesn't exist
+ * everywhere, and this is a fairly trivial function, so we include it */
+static int tagcompare(const char *s1, const char *s2, int n){
+  int c=0;
+  while(c < n){
+    if(toupper(s1[c]) != toupper(s2[c]))
+      return !0;
+    c++;
+  }
+  return 0;
+}
+
+char *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count){
+  long i;
+  int found = 0;
+  int taglen = strlen(tag)+1; /* +1 for the = we append */
+  char *fulltag = alloca(taglen+ 1);
+
+  strcpy(fulltag, tag);
+  strcat(fulltag, "=");
+
+  for(i=0;i<vc->comments;i++){
+    if(!tagcompare(vc->user_comments[i], fulltag, taglen)){
+      if(count == found)
+        /* We return a pointer to the data, not a copy */
+              return vc->user_comments[i] + taglen;
+      else
+        found++;
+    }
+  }
+  return NULL; /* didn't find anything */
+}
+
+int vorbis_comment_query_count(vorbis_comment *vc, const char *tag){
+  int i,count=0;
+  int taglen = strlen(tag)+1; /* +1 for the = we append */
+  char *fulltag = alloca(taglen+1);
+  strcpy(fulltag,tag);
+  strcat(fulltag, "=");
+
+  for(i=0;i<vc->comments;i++){
+    if(!tagcompare(vc->user_comments[i], fulltag, taglen))
+      count++;
+  }
+
+  return count;
+}
+
+void vorbis_comment_clear(vorbis_comment *vc){
+  if(vc){
+    long i;
+    if(vc->user_comments){
+      for(i=0;i<vc->comments;i++)
+        if(vc->user_comments[i])_ogg_free(vc->user_comments[i]);
+      _ogg_free(vc->user_comments);
+    }
+    if(vc->comment_lengths)_ogg_free(vc->comment_lengths);
+    if(vc->vendor)_ogg_free(vc->vendor);
+    memset(vc,0,sizeof(*vc));
+  }
+}
+
+/* blocksize 0 is guaranteed to be short, 1 is guaranteed to be long.
+   They may be equal, but short will never ge greater than long */
+int vorbis_info_blocksize(vorbis_info *vi,int zo){
+  codec_setup_info *ci = vi->codec_setup;
+  return ci ? ci->blocksizes[zo] : -1;
+}
+
+/* used by synthesis, which has a full, alloced vi */
+void vorbis_info_init(vorbis_info *vi){
+  memset(vi,0,sizeof(*vi));
+  vi->codec_setup=_ogg_calloc(1,sizeof(codec_setup_info));
+}
+
+void vorbis_info_clear(vorbis_info *vi){
+  codec_setup_info     *ci=vi->codec_setup;
+  int i;
+
+  if(ci){
+
+    for(i=0;i<ci->modes;i++)
+      if(ci->mode_param[i])_ogg_free(ci->mode_param[i]);
+
+    for(i=0;i<ci->maps;i++) /* unpack does the range checking */
+      if(ci->map_param[i]) /* this may be cleaning up an aborted
+                              unpack, in which case the below type
+                              cannot be trusted */
+        _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]);
+
+    for(i=0;i<ci->floors;i++) /* unpack does the range checking */
+      if(ci->floor_param[i]) /* this may be cleaning up an aborted
+                                unpack, in which case the below type
+                                cannot be trusted */
+        _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]);
+
+    for(i=0;i<ci->residues;i++) /* unpack does the range checking */
+      if(ci->residue_param[i]) /* this may be cleaning up an aborted
+                                  unpack, in which case the below type
+                                  cannot be trusted */
+        _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]);
+
+    for(i=0;i<ci->books;i++){
+      if(ci->book_param[i]){
+        /* knows if the book was not alloced */
+        vorbis_staticbook_destroy(ci->book_param[i]);
+      }
+      if(ci->fullbooks)
+        vorbis_book_clear(ci->fullbooks+i);
+    }
+    if(ci->fullbooks)
+        _ogg_free(ci->fullbooks);
+
+    for(i=0;i<ci->psys;i++)
+      _vi_psy_free(ci->psy_param[i]);
+
+    _ogg_free(ci);
+  }
+
+  memset(vi,0,sizeof(*vi));
+}
+
+/* Header packing/unpacking ********************************************/
+
+static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
+  codec_setup_info     *ci=vi->codec_setup;
+  if(!ci)return(OV_EFAULT);
+
+  vi->version=oggpack_read(opb,32);
+  if(vi->version!=0)return(OV_EVERSION);
+
+  vi->channels=oggpack_read(opb,8);
+  vi->rate=oggpack_read(opb,32);
+
+  vi->bitrate_upper=oggpack_read(opb,32);
+  vi->bitrate_nominal=oggpack_read(opb,32);
+  vi->bitrate_lower=oggpack_read(opb,32);
+
+  ci->blocksizes[0]=1<<oggpack_read(opb,4);
+  ci->blocksizes[1]=1<<oggpack_read(opb,4);
+
+  if(vi->rate<1)goto err_out;
+  if(vi->channels<1)goto err_out;
+  if(ci->blocksizes[0]<64)goto err_out;
+  if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out;
+  if(ci->blocksizes[1]>8192)goto err_out;
+
+  if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
+
+  return(0);
+ err_out:
+  vorbis_info_clear(vi);
+  return(OV_EBADHEADER);
+}
+
+static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
+  int i;
+  int vendorlen=oggpack_read(opb,32);
+  if(vendorlen<0)goto err_out;
+  if(vendorlen>opb->storage-8)goto err_out;
+  vc->vendor=_ogg_calloc(vendorlen+1,1);
+  _v_readstring(opb,vc->vendor,vendorlen);
+  i=oggpack_read(opb,32);
+  if(i<0)goto err_out;
+  if(i>((opb->storage-oggpack_bytes(opb))>>2))goto err_out;
+  vc->comments=i;
+  vc->user_comments=_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments));
+  vc->comment_lengths=_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths));
+
+  for(i=0;i<vc->comments;i++){
+    int len=oggpack_read(opb,32);
+    if(len<0)goto err_out;
+    if(len>opb->storage-oggpack_bytes(opb))goto err_out;
+    vc->comment_lengths[i]=len;
+    vc->user_comments[i]=_ogg_calloc(len+1,1);
+    _v_readstring(opb,vc->user_comments[i],len);
+  }
+  if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */
+
+  return(0);
+ err_out:
+  vorbis_comment_clear(vc);
+  return(OV_EBADHEADER);
+}
+
+/* all of the real encoding details are here.  The modes, books,
+   everything */
+static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
+  codec_setup_info     *ci=vi->codec_setup;
+  int i;
+  if(!ci)return(OV_EFAULT);
+
+  /* codebooks */
+  ci->books=oggpack_read(opb,8)+1;
+  if(ci->books<=0)goto err_out;
+  for(i=0;i<ci->books;i++){
+    ci->book_param[i]=vorbis_staticbook_unpack(opb);
+    if(!ci->book_param[i])goto err_out;
+  }
+
+  /* time backend settings; hooks are unused */
+  {
+    int times=oggpack_read(opb,6)+1;
+    if(times<=0)goto err_out;
+    for(i=0;i<times;i++){
+      int test=oggpack_read(opb,16);
+      if(test<0 || test>=VI_TIMEB)goto err_out;
+    }
+  }
+
+  /* floor backend settings */
+  ci->floors=oggpack_read(opb,6)+1;
+  if(ci->floors<=0)goto err_out;
+  for(i=0;i<ci->floors;i++){
+    ci->floor_type[i]=oggpack_read(opb,16);
+    if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out;
+    ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb);
+    if(!ci->floor_param[i])goto err_out;
+  }
+
+  /* residue backend settings */
+  ci->residues=oggpack_read(opb,6)+1;
+  if(ci->residues<=0)goto err_out;
+  for(i=0;i<ci->residues;i++){
+    ci->residue_type[i]=oggpack_read(opb,16);
+    if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out;
+    ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb);
+    if(!ci->residue_param[i])goto err_out;
+  }
+
+  /* map backend settings */
+  ci->maps=oggpack_read(opb,6)+1;
+  if(ci->maps<=0)goto err_out;
+  for(i=0;i<ci->maps;i++){
+    ci->map_type[i]=oggpack_read(opb,16);
+    if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out;
+    ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb);
+    if(!ci->map_param[i])goto err_out;
+  }
+
+  /* mode settings */
+  ci->modes=oggpack_read(opb,6)+1;
+  if(ci->modes<=0)goto err_out;
+  for(i=0;i<ci->modes;i++){
+    ci->mode_param[i]=_ogg_calloc(1,sizeof(*ci->mode_param[i]));
+    ci->mode_param[i]->blockflag=oggpack_read(opb,1);
+    ci->mode_param[i]->windowtype=oggpack_read(opb,16);
+    ci->mode_param[i]->transformtype=oggpack_read(opb,16);
+    ci->mode_param[i]->mapping=oggpack_read(opb,8);
+
+    if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out;
+    if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out;
+    if(ci->mode_param[i]->mapping>=ci->maps)goto err_out;
+    if(ci->mode_param[i]->mapping<0)goto err_out;
+  }
+
+  if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */
+
+  return(0);
+ err_out:
+  vorbis_info_clear(vi);
+  return(OV_EBADHEADER);
+}
+
+/* Is this packet a vorbis ID header? */
+int vorbis_synthesis_idheader(ogg_packet *op){
+  oggpack_buffer opb;
+  char buffer[6];
+
+  if(op){
+    oggpack_readinit(&opb,op->packet,op->bytes);
+
+    if(!op->b_o_s)
+      return(0); /* Not the initial packet */
+
+    if(oggpack_read(&opb,8) != 1)
+      return 0; /* not an ID header */
+
+    memset(buffer,0,6);
+    _v_readstring(&opb,buffer,6);
+    if(memcmp(buffer,"vorbis",6))
+      return 0; /* not vorbis */
+
+    return 1;
+  }
+
+  return 0;
+}
+
+/* The Vorbis header is in three packets; the initial small packet in
+   the first page that identifies basic parameters, a second packet
+   with bitstream comments and a third packet that holds the
+   codebook. */
+
+int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){
+  oggpack_buffer opb;
+
+  if(op){
+    oggpack_readinit(&opb,op->packet,op->bytes);
+
+    /* Which of the three types of header is this? */
+    /* Also verify header-ness, vorbis */
+    {
+      char buffer[6];
+      int packtype=oggpack_read(&opb,8);
+      memset(buffer,0,6);
+      _v_readstring(&opb,buffer,6);
+      if(memcmp(buffer,"vorbis",6)){
+        /* not a vorbis header */
+        return(OV_ENOTVORBIS);
+      }
+      switch(packtype){
+      case 0x01: /* least significant *bit* is read first */
+        if(!op->b_o_s){
+          /* Not the initial packet */
+          return(OV_EBADHEADER);
+        }
+        if(vi->rate!=0){
+          /* previously initialized info header */
+          return(OV_EBADHEADER);
+        }
+
+        return(_vorbis_unpack_info(vi,&opb));
+
+      case 0x03: /* least significant *bit* is read first */
+        if(vi->rate==0){
+          /* um... we didn't get the initial header */
+          return(OV_EBADHEADER);
+        }
+
+        return(_vorbis_unpack_comment(vc,&opb));
+
+      case 0x05: /* least significant *bit* is read first */
+        if(vi->rate==0 || vc->vendor==NULL){
+          /* um... we didn;t get the initial header or comments yet */
+          return(OV_EBADHEADER);
+        }
+
+        return(_vorbis_unpack_books(vi,&opb));
+
+      default:
+        /* Not a valid vorbis header type */
+        return(OV_EBADHEADER);
+        break;
+      }
+    }
+  }
+  return(OV_EBADHEADER);
+}
+
+/* pack side **********************************************************/
+
+int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
+  codec_setup_info     *ci=vi->codec_setup;
+  if(!ci)return(OV_EFAULT);
+
+  /* preamble */
+  oggpack_write(opb,0x01,8);
+  _v_writestring(opb,"vorbis", 6);
+
+  /* basic information about the stream */
+  oggpack_write(opb,0x00,32);
+  oggpack_write(opb,vi->channels,8);
+  oggpack_write(opb,vi->rate,32);
+
+  oggpack_write(opb,vi->bitrate_upper,32);
+  oggpack_write(opb,vi->bitrate_nominal,32);
+  oggpack_write(opb,vi->bitrate_lower,32);
+
+  oggpack_write(opb,ilog2(ci->blocksizes[0]),4);
+  oggpack_write(opb,ilog2(ci->blocksizes[1]),4);
+  oggpack_write(opb,1,1);
+
+  return(0);
+}
+
+int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){
+  int bytes = strlen(ENCODE_VENDOR_STRING);
+
+  /* preamble */
+  oggpack_write(opb,0x03,8);
+  _v_writestring(opb,"vorbis", 6);
+
+  /* vendor */
+  oggpack_write(opb,bytes,32);
+  _v_writestring(opb,ENCODE_VENDOR_STRING, bytes);
+
+  /* comments */
+
+  oggpack_write(opb,vc->comments,32);
+  if(vc->comments){
+    int i;
+    for(i=0;i<vc->comments;i++){
+      if(vc->user_comments[i]){
+        oggpack_write(opb,vc->comment_lengths[i],32);
+        _v_writestring(opb,vc->user_comments[i], vc->comment_lengths[i]);
+      }else{
+        oggpack_write(opb,0,32);
+      }
+    }
+  }
+  oggpack_write(opb,1,1);
+
+  return(0);
+}
+
+int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){
+  codec_setup_info     *ci=vi->codec_setup;
+  int i;
+  if(!ci)return(OV_EFAULT);
+
+  oggpack_write(opb,0x05,8);
+  _v_writestring(opb,"vorbis", 6);
+
+  /* books */
+  oggpack_write(opb,ci->books-1,8);
+  for(i=0;i<ci->books;i++)
+    if(vorbis_staticbook_pack(ci->book_param[i],opb))goto err_out;
+
+  /* times; hook placeholders */
+  oggpack_write(opb,0,6);
+  oggpack_write(opb,0,16);
+
+  /* floors */
+  oggpack_write(opb,ci->floors-1,6);
+  for(i=0;i<ci->floors;i++){
+    oggpack_write(opb,ci->floor_type[i],16);
+    if(_floor_P[ci->floor_type[i]]->pack)
+      _floor_P[ci->floor_type[i]]->pack(ci->floor_param[i],opb);
+    else
+      goto err_out;
+  }
+
+  /* residues */
+  oggpack_write(opb,ci->residues-1,6);
+  for(i=0;i<ci->residues;i++){
+    oggpack_write(opb,ci->residue_type[i],16);
+    _residue_P[ci->residue_type[i]]->pack(ci->residue_param[i],opb);
+  }
+
+  /* maps */
+  oggpack_write(opb,ci->maps-1,6);
+  for(i=0;i<ci->maps;i++){
+    oggpack_write(opb,ci->map_type[i],16);
+    _mapping_P[ci->map_type[i]]->pack(vi,ci->map_param[i],opb);
+  }
+
+  /* modes */
+  oggpack_write(opb,ci->modes-1,6);
+  for(i=0;i<ci->modes;i++){
+    oggpack_write(opb,ci->mode_param[i]->blockflag,1);
+    oggpack_write(opb,ci->mode_param[i]->windowtype,16);
+    oggpack_write(opb,ci->mode_param[i]->transformtype,16);
+    oggpack_write(opb,ci->mode_param[i]->mapping,8);
+  }
+  oggpack_write(opb,1,1);
+
+  return(0);
+err_out:
+  return(-1);
+}
+
+int vorbis_commentheader_out(vorbis_comment *vc,
+                                          ogg_packet *op){
+
+  oggpack_buffer opb;
+
+  oggpack_writeinit(&opb);
+  if(_vorbis_pack_comment(&opb,vc)){
+    oggpack_writeclear(&opb);
+    return OV_EIMPL;
+  }
+
+  op->packet = _ogg_malloc(oggpack_bytes(&opb));
+  memcpy(op->packet, opb.buffer, oggpack_bytes(&opb));
+
+  op->bytes=oggpack_bytes(&opb);
+  op->b_o_s=0;
+  op->e_o_s=0;
+  op->granulepos=0;
+  op->packetno=1;
+
+  oggpack_writeclear(&opb);
+  return 0;
+}
+
+int vorbis_analysis_headerout(vorbis_dsp_state *v,
+                              vorbis_comment *vc,
+                              ogg_packet *op,
+                              ogg_packet *op_comm,
+                              ogg_packet *op_code){
+  int ret=OV_EIMPL;
+  vorbis_info *vi=v->vi;
+  oggpack_buffer opb;
+  private_state *b=v->backend_state;
+
+  if(!b){
+    ret=OV_EFAULT;
+    goto err_out;
+  }
+
+  /* first header packet **********************************************/
+
+  oggpack_writeinit(&opb);
+  if(_vorbis_pack_info(&opb,vi))goto err_out;
+
+  /* build the packet */
+  if(b->header)_ogg_free(b->header);
+  b->header=_ogg_malloc(oggpack_bytes(&opb));
+  memcpy(b->header,opb.buffer,oggpack_bytes(&opb));
+  op->packet=b->header;
+  op->bytes=oggpack_bytes(&opb);
+  op->b_o_s=1;
+  op->e_o_s=0;
+  op->granulepos=0;
+  op->packetno=0;
+
+  /* second header packet (comments) **********************************/
+
+  oggpack_reset(&opb);
+  if(_vorbis_pack_comment(&opb,vc))goto err_out;
+
+  if(b->header1)_ogg_free(b->header1);
+  b->header1=_ogg_malloc(oggpack_bytes(&opb));
+  memcpy(b->header1,opb.buffer,oggpack_bytes(&opb));
+  op_comm->packet=b->header1;
+  op_comm->bytes=oggpack_bytes(&opb);
+  op_comm->b_o_s=0;
+  op_comm->e_o_s=0;
+  op_comm->granulepos=0;
+  op_comm->packetno=1;
+
+  /* third header packet (modes/codebooks) ****************************/
+
+  oggpack_reset(&opb);
+  if(_vorbis_pack_books(&opb,vi))goto err_out;
+
+  if(b->header2)_ogg_free(b->header2);
+  b->header2=_ogg_malloc(oggpack_bytes(&opb));
+  memcpy(b->header2,opb.buffer,oggpack_bytes(&opb));
+  op_code->packet=b->header2;
+  op_code->bytes=oggpack_bytes(&opb);
+  op_code->b_o_s=0;
+  op_code->e_o_s=0;
+  op_code->granulepos=0;
+  op_code->packetno=2;
+
+  oggpack_writeclear(&opb);
+  return(0);
+ err_out:
+  memset(op,0,sizeof(*op));
+  memset(op_comm,0,sizeof(*op_comm));
+  memset(op_code,0,sizeof(*op_code));
+
+  if(b){
+    oggpack_writeclear(&opb);
+    if(b->header)_ogg_free(b->header);
+    if(b->header1)_ogg_free(b->header1);
+    if(b->header2)_ogg_free(b->header2);
+    b->header=NULL;
+    b->header1=NULL;
+    b->header2=NULL;
+  }
+  return(ret);
+}
+
+double vorbis_granule_time(vorbis_dsp_state *v,ogg_int64_t granulepos){
+  if(granulepos == -1) return -1;
+
+  /* We're not guaranteed a 64 bit unsigned type everywhere, so we
+     have to put the unsigned granpo in a signed type. */
+  if(granulepos>=0){
+    return((double)granulepos/v->vi->rate);
+  }else{
+    ogg_int64_t granuleoff=0xffffffff;
+    granuleoff<<=31;
+    granuleoff|=0x7ffffffff;
+    return(((double)granulepos+2+granuleoff+granuleoff)/v->vi->rate);
+  }
+}
+
+const char *vorbis_version_string(void){
+  return GENERAL_VENDOR_STRING;
+}

+ 94 - 0
liboggvorbis/src/lookup.c

@@ -0,0 +1,94 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function: lookup based functions
+  last mod: $Id: lookup.c 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+#include <math.h>
+#include "lookup.h"
+#include "lookup_data.h"
+#include "os.h"
+#include "misc.h"
+
+#ifdef FLOAT_LOOKUP
+
+/* interpolated lookup based cos function, domain 0 to PI only */
+float vorbis_coslook(float a){
+  double d=a*(.31830989*(float)COS_LOOKUP_SZ);
+  int i=vorbis_ftoi(d-.5);
+
+  return COS_LOOKUP[i]+ (d-i)*(COS_LOOKUP[i+1]-COS_LOOKUP[i]);
+}
+
+/* interpolated 1./sqrt(p) where .5 <= p < 1. */
+float vorbis_invsqlook(float a){
+  double d=a*(2.f*(float)INVSQ_LOOKUP_SZ)-(float)INVSQ_LOOKUP_SZ;
+  int i=vorbis_ftoi(d-.5f);
+  return INVSQ_LOOKUP[i]+ (d-i)*(INVSQ_LOOKUP[i+1]-INVSQ_LOOKUP[i]);
+}
+
+/* interpolated 1./sqrt(p) where .5 <= p < 1. */
+float vorbis_invsq2explook(int a){
+  return INVSQ2EXP_LOOKUP[a-INVSQ2EXP_LOOKUP_MIN];
+}
+
+#include <stdio.h>
+/* interpolated lookup based fromdB function, domain -140dB to 0dB only */
+float vorbis_fromdBlook(float a){
+  int i=vorbis_ftoi(a*((float)(-(1<<FROMdB2_SHIFT)))-.5f);
+  return (i<0)?1.f:
+    ((i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))?0.f:
+     FROMdB_LOOKUP[i>>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]);
+}
+
+#endif
+
+#ifdef INT_LOOKUP
+/* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in
+   16.16 format
+
+   returns in m.8 format */
+long vorbis_invsqlook_i(long a,long e){
+  long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1);
+  long d=(a&INVSQ_LOOKUP_I_MASK)<<(16-INVSQ_LOOKUP_I_SHIFT); /*  0.16 */
+  long val=INVSQ_LOOKUP_I[i]-                                /*  1.16 */
+    (((INVSQ_LOOKUP_I[i]-INVSQ_LOOKUP_I[i+1])*               /*  0.16 */
+      d)>>16);                                               /* result 1.16 */
+
+  e+=32;
+  if(e&1)val=(val*5792)>>13; /* multiply val by 1/sqrt(2) */
+  e=(e>>1)-8;
+
+  return(val>>e);
+}
+
+/* interpolated lookup based fromdB function, domain -140dB to 0dB only */
+/* a is in n.12 format */
+float vorbis_fromdBlook_i(long a){
+  int i=(-a)>>(12-FROMdB2_SHIFT);
+  return (i<0)?1.f:
+    ((i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))?0.f:
+     FROMdB_LOOKUP[i>>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]);
+}
+
+/* interpolated lookup based cos function, domain 0 to PI only */
+/* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
+long vorbis_coslook_i(long a){
+  int i=a>>COS_LOOKUP_I_SHIFT;
+  int d=a&COS_LOOKUP_I_MASK;
+  return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
+                           COS_LOOKUP_I_SHIFT);
+}
+
+#endif

+ 32 - 0
liboggvorbis/src/lookup.h

@@ -0,0 +1,32 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function: lookup based functions
+  last mod: $Id: lookup.h 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _V_LOOKUP_H_
+
+#ifdef FLOAT_LOOKUP
+extern float vorbis_coslook(float a);
+extern float vorbis_invsqlook(float a);
+extern float vorbis_invsq2explook(int a);
+extern float vorbis_fromdBlook(float a);
+#endif
+#ifdef INT_LOOKUP
+extern long vorbis_invsqlook_i(long a,long e);
+extern long vorbis_coslook_i(long a);
+extern float vorbis_fromdBlook_i(long a);
+#endif
+
+#endif

+ 192 - 0
liboggvorbis/src/lookup_data.h

@@ -0,0 +1,192 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function: lookup data; generated by lookups.pl; edit there
+  last mod: $Id: lookup_data.h 16037 2009-05-26 21:10:58Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _V_LOOKUP_DATA_H_
+
+#ifdef FLOAT_LOOKUP
+#define COS_LOOKUP_SZ 128
+static const float COS_LOOKUP[COS_LOOKUP_SZ+1]={
+        +1.0000000000000f,+0.9996988186962f,+0.9987954562052f,+0.9972904566787f,
+        +0.9951847266722f,+0.9924795345987f,+0.9891765099648f,+0.9852776423889f,
+        +0.9807852804032f,+0.9757021300385f,+0.9700312531945f,+0.9637760657954f,
+        +0.9569403357322f,+0.9495281805930f,+0.9415440651830f,+0.9329927988347f,
+        +0.9238795325113f,+0.9142097557035f,+0.9039892931234f,+0.8932243011955f,
+        +0.8819212643484f,+0.8700869911087f,+0.8577286100003f,+0.8448535652497f,
+        +0.8314696123025f,+0.8175848131516f,+0.8032075314806f,+0.7883464276266f,
+        +0.7730104533627f,+0.7572088465065f,+0.7409511253550f,+0.7242470829515f,
+        +0.7071067811865f,+0.6895405447371f,+0.6715589548470f,+0.6531728429538f,
+        +0.6343932841636f,+0.6152315905806f,+0.5956993044924f,+0.5758081914178f,
+        +0.5555702330196f,+0.5349976198871f,+0.5141027441932f,+0.4928981922298f,
+        +0.4713967368260f,+0.4496113296546f,+0.4275550934303f,+0.4052413140050f,
+        +0.3826834323651f,+0.3598950365350f,+0.3368898533922f,+0.3136817403989f,
+        +0.2902846772545f,+0.2667127574749f,+0.2429801799033f,+0.2191012401569f,
+        +0.1950903220161f,+0.1709618887603f,+0.1467304744554f,+0.1224106751992f,
+        +0.0980171403296f,+0.0735645635997f,+0.0490676743274f,+0.0245412285229f,
+        +0.0000000000000f,-0.0245412285229f,-0.0490676743274f,-0.0735645635997f,
+        -0.0980171403296f,-0.1224106751992f,-0.1467304744554f,-0.1709618887603f,
+        -0.1950903220161f,-0.2191012401569f,-0.2429801799033f,-0.2667127574749f,
+        -0.2902846772545f,-0.3136817403989f,-0.3368898533922f,-0.3598950365350f,
+        -0.3826834323651f,-0.4052413140050f,-0.4275550934303f,-0.4496113296546f,
+        -0.4713967368260f,-0.4928981922298f,-0.5141027441932f,-0.5349976198871f,
+        -0.5555702330196f,-0.5758081914178f,-0.5956993044924f,-0.6152315905806f,
+        -0.6343932841636f,-0.6531728429538f,-0.6715589548470f,-0.6895405447371f,
+        -0.7071067811865f,-0.7242470829515f,-0.7409511253550f,-0.7572088465065f,
+        -0.7730104533627f,-0.7883464276266f,-0.8032075314806f,-0.8175848131516f,
+        -0.8314696123025f,-0.8448535652497f,-0.8577286100003f,-0.8700869911087f,
+        -0.8819212643484f,-0.8932243011955f,-0.9039892931234f,-0.9142097557035f,
+        -0.9238795325113f,-0.9329927988347f,-0.9415440651830f,-0.9495281805930f,
+        -0.9569403357322f,-0.9637760657954f,-0.9700312531945f,-0.9757021300385f,
+        -0.9807852804032f,-0.9852776423889f,-0.9891765099648f,-0.9924795345987f,
+        -0.9951847266722f,-0.9972904566787f,-0.9987954562052f,-0.9996988186962f,
+        -1.0000000000000f,
+};
+
+#define INVSQ_LOOKUP_SZ 32
+static const float INVSQ_LOOKUP[INVSQ_LOOKUP_SZ+1]={
+        1.414213562373f,1.392621247646f,1.371988681140f,1.352246807566f,
+        1.333333333333f,1.315191898443f,1.297771369046f,1.281025230441f,
+        1.264911064067f,1.249390095109f,1.234426799697f,1.219988562661f,
+        1.206045378311f,1.192569588000f,1.179535649239f,1.166919931983f,
+        1.154700538379f,1.142857142857f,1.131370849898f,1.120224067222f,
+        1.109400392450f,1.098884511590f,1.088662107904f,1.078719779941f,
+        1.069044967650f,1.059625885652f,1.050451462878f,1.041511287847f,
+        1.032795558989f,1.024295039463f,1.016001016002f,1.007905261358f,
+        1.000000000000f,
+};
+
+#define INVSQ2EXP_LOOKUP_MIN (-32)
+#define INVSQ2EXP_LOOKUP_MAX 32
+static const float INVSQ2EXP_LOOKUP[INVSQ2EXP_LOOKUP_MAX-\
+                              INVSQ2EXP_LOOKUP_MIN+1]={
+                 65536.f,    46340.95001f,         32768.f,    23170.47501f,
+                 16384.f,     11585.2375f,          8192.f,    5792.618751f,
+                  4096.f,    2896.309376f,          2048.f,    1448.154688f,
+                  1024.f,    724.0773439f,           512.f,     362.038672f,
+                   256.f,     181.019336f,           128.f,    90.50966799f,
+                    64.f,      45.254834f,            32.f,      22.627417f,
+                    16.f,     11.3137085f,             8.f,    5.656854249f,
+                     4.f,    2.828427125f,             2.f,    1.414213562f,
+                     1.f,   0.7071067812f,            0.5f,   0.3535533906f,
+                   0.25f,   0.1767766953f,          0.125f,  0.08838834765f,
+                 0.0625f,  0.04419417382f,        0.03125f,  0.02209708691f,
+               0.015625f,  0.01104854346f,      0.0078125f, 0.005524271728f,
+             0.00390625f, 0.002762135864f,    0.001953125f, 0.001381067932f,
+           0.0009765625f, 0.000690533966f,  0.00048828125f, 0.000345266983f,
+         0.000244140625f,0.0001726334915f,0.0001220703125f,8.631674575e-05f,
+        6.103515625e-05f,4.315837288e-05f,3.051757812e-05f,2.157918644e-05f,
+        1.525878906e-05f,
+};
+
+#endif
+
+#define FROMdB_LOOKUP_SZ 35
+#define FROMdB2_LOOKUP_SZ 32
+#define FROMdB_SHIFT 5
+#define FROMdB2_SHIFT 3
+#define FROMdB2_MASK 31
+
+#ifdef FLOAT_LOOKUP
+static const float FROMdB_LOOKUP[FROMdB_LOOKUP_SZ]={
+                     1.f,   0.6309573445f,   0.3981071706f,   0.2511886432f,
+           0.1584893192f,            0.1f,  0.06309573445f,  0.03981071706f,
+          0.02511886432f,  0.01584893192f,           0.01f, 0.006309573445f,
+         0.003981071706f, 0.002511886432f, 0.001584893192f,          0.001f,
+        0.0006309573445f,0.0003981071706f,0.0002511886432f,0.0001584893192f,
+                 0.0001f,6.309573445e-05f,3.981071706e-05f,2.511886432e-05f,
+        1.584893192e-05f,          1e-05f,6.309573445e-06f,3.981071706e-06f,
+        2.511886432e-06f,1.584893192e-06f,          1e-06f,6.309573445e-07f,
+        3.981071706e-07f,2.511886432e-07f,1.584893192e-07f,
+};
+
+static const float FROMdB2_LOOKUP[FROMdB2_LOOKUP_SZ]={
+           0.9928302478f,   0.9786445908f,   0.9646616199f,   0.9508784391f,
+           0.9372921937f,     0.92390007f,   0.9106992942f,   0.8976871324f,
+           0.8848608897f,   0.8722179097f,   0.8597555737f,   0.8474713009f,
+            0.835362547f,   0.8234268041f,   0.8116616003f,   0.8000644989f,
+           0.7886330981f,   0.7773650302f,   0.7662579617f,    0.755309592f,
+           0.7445176537f,   0.7338799116f,   0.7233941627f,   0.7130582353f,
+           0.7028699885f,   0.6928273125f,   0.6829281272f,   0.6731703824f,
+           0.6635520573f,   0.6540711597f,   0.6447257262f,   0.6355138211f,
+};
+#endif
+
+#ifdef INT_LOOKUP
+
+#define INVSQ_LOOKUP_I_SHIFT 10
+#define INVSQ_LOOKUP_I_MASK 1023
+static const long INVSQ_LOOKUP_I[64+1]={
+           92682l,   91966l,   91267l,   90583l,
+           89915l,   89261l,   88621l,   87995l,
+           87381l,   86781l,   86192l,   85616l,
+           85051l,   84497l,   83953l,   83420l,
+           82897l,   82384l,   81880l,   81385l,
+           80899l,   80422l,   79953l,   79492l,
+           79039l,   78594l,   78156l,   77726l,
+           77302l,   76885l,   76475l,   76072l,
+           75674l,   75283l,   74898l,   74519l,
+           74146l,   73778l,   73415l,   73058l,
+           72706l,   72359l,   72016l,   71679l,
+           71347l,   71019l,   70695l,   70376l,
+           70061l,   69750l,   69444l,   69141l,
+           68842l,   68548l,   68256l,   67969l,
+           67685l,   67405l,   67128l,   66855l,
+           66585l,   66318l,   66054l,   65794l,
+           65536l,
+};
+
+#define COS_LOOKUP_I_SHIFT 9
+#define COS_LOOKUP_I_MASK 511
+#define COS_LOOKUP_I_SZ 128
+static const long COS_LOOKUP_I[COS_LOOKUP_I_SZ+1]={
+           16384l,   16379l,   16364l,   16340l,
+           16305l,   16261l,   16207l,   16143l,
+           16069l,   15986l,   15893l,   15791l,
+           15679l,   15557l,   15426l,   15286l,
+           15137l,   14978l,   14811l,   14635l,
+           14449l,   14256l,   14053l,   13842l,
+           13623l,   13395l,   13160l,   12916l,
+           12665l,   12406l,   12140l,   11866l,
+           11585l,   11297l,   11003l,   10702l,
+           10394l,   10080l,    9760l,    9434l,
+            9102l,    8765l,    8423l,    8076l,
+            7723l,    7366l,    7005l,    6639l,
+            6270l,    5897l,    5520l,    5139l,
+            4756l,    4370l,    3981l,    3590l,
+            3196l,    2801l,    2404l,    2006l,
+            1606l,    1205l,     804l,     402l,
+               0l,    -401l,    -803l,   -1204l,
+           -1605l,   -2005l,   -2403l,   -2800l,
+           -3195l,   -3589l,   -3980l,   -4369l,
+           -4755l,   -5138l,   -5519l,   -5896l,
+           -6269l,   -6638l,   -7004l,   -7365l,
+           -7722l,   -8075l,   -8422l,   -8764l,
+           -9101l,   -9433l,   -9759l,  -10079l,
+          -10393l,  -10701l,  -11002l,  -11296l,
+          -11584l,  -11865l,  -12139l,  -12405l,
+          -12664l,  -12915l,  -13159l,  -13394l,
+          -13622l,  -13841l,  -14052l,  -14255l,
+          -14448l,  -14634l,  -14810l,  -14977l,
+          -15136l,  -15285l,  -15425l,  -15556l,
+          -15678l,  -15790l,  -15892l,  -15985l,
+          -16068l,  -16142l,  -16206l,  -16260l,
+          -16304l,  -16339l,  -16363l,  -16378l,
+          -16383l,
+};
+
+#endif
+
+#endif

+ 160 - 0
liboggvorbis/src/lpc.c

@@ -0,0 +1,160 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function: LPC low level routines
+  last mod: $Id: lpc.c 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+/* Some of these routines (autocorrelator, LPC coefficient estimator)
+   are derived from code written by Jutta Degener and Carsten Bormann;
+   thus we include their copyright below.  The entirety of this file
+   is freely redistributable on the condition that both of these
+   copyright notices are preserved without modification.  */
+
+/* Preserved Copyright: *********************************************/
+
+/* Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
+Technische Universita"t Berlin
+
+Any use of this software is permitted provided that this notice is not
+removed and that neither the authors nor the Technische Universita"t
+Berlin are deemed to have made any representations as to the
+suitability of this software for any purpose nor are held responsible
+for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR
+THIS SOFTWARE.
+
+As a matter of courtesy, the authors request to be informed about uses
+this software has found, about bugs in this software, and about any
+improvements that may be of general interest.
+
+Berlin, 28.11.1994
+Jutta Degener
+Carsten Bormann
+
+*********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "os.h"
+#include "smallft.h"
+#include "lpc.h"
+#include "scales.h"
+#include "misc.h"
+
+/* Autocorrelation LPC coeff generation algorithm invented by
+   N. Levinson in 1947, modified by J. Durbin in 1959. */
+
+/* Input : n elements of time doamin data
+   Output: m lpc coefficients, excitation energy */
+
+float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){
+  double *aut=alloca(sizeof(*aut)*(m+1));
+  double *lpc=alloca(sizeof(*lpc)*(m));
+  double error;
+  double epsilon;
+  int i,j;
+
+  /* autocorrelation, p+1 lag coefficients */
+  j=m+1;
+  while(j--){
+    double d=0; /* double needed for accumulator depth */
+    for(i=j;i<n;i++)d+=(double)data[i]*data[i-j];
+    aut[j]=d;
+  }
+
+  /* Generate lpc coefficients from autocorr values */
+
+  /* set our noise floor to about -100dB */
+  error=aut[0] * (1. + 1e-10);
+  epsilon=1e-9*aut[0]+1e-10;
+
+  for(i=0;i<m;i++){
+    double r= -aut[i+1];
+
+    if(error<epsilon){
+      memset(lpc+i,0,(m-i)*sizeof(*lpc));
+      goto done;
+    }
+
+    /* Sum up this iteration's reflection coefficient; note that in
+       Vorbis we don't save it.  If anyone wants to recycle this code
+       and needs reflection coefficients, save the results of 'r' from
+       each iteration. */
+
+    for(j=0;j<i;j++)r-=lpc[j]*aut[i-j];
+    r/=error;
+
+    /* Update LPC coefficients and total error */
+
+    lpc[i]=r;
+    for(j=0;j<i/2;j++){
+      double tmp=lpc[j];
+
+      lpc[j]+=r*lpc[i-1-j];
+      lpc[i-1-j]+=r*tmp;
+    }
+    if(i&1)lpc[j]+=lpc[j]*r;
+
+    error*=1.-r*r;
+
+  }
+
+ done:
+
+  /* slightly damp the filter */
+  {
+    double g = .99;
+    double damp = g;
+    for(j=0;j<m;j++){
+      lpc[j]*=damp;
+      damp*=g;
+    }
+  }
+
+  for(j=0;j<m;j++)lpci[j]=(float)lpc[j];
+
+  /* we need the error value to know how big an impulse to hit the
+     filter with later */
+
+  return error;
+}
+
+void vorbis_lpc_predict(float *coeff,float *prime,int m,
+                     float *data,long n){
+
+  /* in: coeff[0...m-1] LPC coefficients
+         prime[0...m-1] initial values (allocated size of n+m-1)
+    out: data[0...n-1] data samples */
+
+  long i,j,o,p;
+  float y;
+  float *work=alloca(sizeof(*work)*(m+n));
+
+  if(!prime)
+    for(i=0;i<m;i++)
+      work[i]=0.f;
+  else
+    for(i=0;i<m;i++)
+      work[i]=prime[i];
+
+  for(i=0;i<n;i++){
+    y=0;
+    o=i;
+    p=m;
+    for(j=0;j<m;j++)
+      y-=work[o++]*coeff[--p];
+
+    data[i]=work[o]=y;
+  }
+}

+ 29 - 0
liboggvorbis/src/lpc.h

@@ -0,0 +1,29 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function: LPC low level routines
+  last mod: $Id: lpc.h 16037 2009-05-26 21:10:58Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _V_LPC_H_
+#define _V_LPC_H_
+
+#include "vorbis/codec.h"
+
+/* simple linear scale LPC code */
+extern float vorbis_lpc_from_data(float *data,float *lpc,int n,int m);
+
+extern void vorbis_lpc_predict(float *coeff,float *prime,int m,
+                               float *data,long n);
+
+#endif

+ 456 - 0
liboggvorbis/src/lsp.c

@@ -0,0 +1,456 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function: LSP (also called LSF) conversion routines
+  last mod: $Id: lsp.c 17538 2010-10-15 02:52:29Z tterribe $
+
+  The LSP generation code is taken (with minimal modification and a
+  few bugfixes) from "On the Computation of the LSP Frequencies" by
+  Joseph Rothweiler (see http://www.rothweiler.us for contact info).
+  The paper is available at:
+
+  http://www.myown1.com/joe/lsf
+
+ ********************************************************************/
+
+/* Note that the lpc-lsp conversion finds the roots of polynomial with
+   an iterative root polisher (CACM algorithm 283).  It *is* possible
+   to confuse this algorithm into not converging; that should only
+   happen with absurdly closely spaced roots (very sharp peaks in the
+   LPC f response) which in turn should be impossible in our use of
+   the code.  If this *does* happen anyway, it's a bug in the floor
+   finder; find the cause of the confusion (probably a single bin
+   spike or accidental near-float-limit resolution problems) and
+   correct it. */
+
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include "lsp.h"
+#include "os.h"
+#include "misc.h"
+#include "lookup.h"
+#include "scales.h"
+
+/* three possible LSP to f curve functions; the exact computation
+   (float), a lookup based float implementation, and an integer
+   implementation.  The float lookup is likely the optimal choice on
+   any machine with an FPU.  The integer implementation is *not* fixed
+   point (due to the need for a large dynamic range and thus a
+   separately tracked exponent) and thus much more complex than the
+   relatively simple float implementations. It's mostly for future
+   work on a fully fixed point implementation for processors like the
+   ARM family. */
+
+/* define either of these (preferably FLOAT_LOOKUP) to have faster
+   but less precise implementation. */
+#undef FLOAT_LOOKUP
+#undef INT_LOOKUP
+
+#ifdef FLOAT_LOOKUP
+#include "lookup.c" /* catch this in the build system; we #include for
+                       compilers (like gcc) that can't inline across
+                       modules */
+
+/* side effect: changes *lsp to cosines of lsp */
+void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m,
+                            float amp,float ampoffset){
+  int i;
+  float wdel=M_PI/ln;
+  vorbis_fpu_control fpu;
+
+  vorbis_fpu_setround(&fpu);
+  for(i=0;i<m;i++)lsp[i]=vorbis_coslook(lsp[i]);
+
+  i=0;
+  while(i<n){
+    int k=map[i];
+    int qexp;
+    float p=.7071067812f;
+    float q=.7071067812f;
+    float w=vorbis_coslook(wdel*k);
+    float *ftmp=lsp;
+    int c=m>>1;
+
+    while(c--){
+      q*=ftmp[0]-w;
+      p*=ftmp[1]-w;
+      ftmp+=2;
+    }
+
+    if(m&1){
+      /* odd order filter; slightly assymetric */
+      /* the last coefficient */
+      q*=ftmp[0]-w;
+      q*=q;
+      p*=p*(1.f-w*w);
+    }else{
+      /* even order filter; still symmetric */
+      q*=q*(1.f+w);
+      p*=p*(1.f-w);
+    }
+
+    q=frexp(p+q,&qexp);
+    q=vorbis_fromdBlook(amp*
+                        vorbis_invsqlook(q)*
+                        vorbis_invsq2explook(qexp+m)-
+                        ampoffset);
+
+    do{
+      curve[i++]*=q;
+    }while(map[i]==k);
+  }
+  vorbis_fpu_restore(fpu);
+}
+
+#else
+
+#ifdef INT_LOOKUP
+#include "lookup.c" /* catch this in the build system; we #include for
+                       compilers (like gcc) that can't inline across
+                       modules */
+
+static const int MLOOP_1[64]={
+   0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13,
+  14,14,14,14, 14,14,14,14, 14,14,14,14, 14,14,14,14,
+  15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15,
+  15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15,
+};
+
+static const int MLOOP_2[64]={
+  0,4,5,5, 6,6,6,6, 7,7,7,7, 7,7,7,7,
+  8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,
+  9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
+  9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
+};
+
+static const int MLOOP_3[8]={0,1,2,2,3,3,3,3};
+
+
+/* side effect: changes *lsp to cosines of lsp */
+void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m,
+                            float amp,float ampoffset){
+
+  /* 0 <= m < 256 */
+
+  /* set up for using all int later */
+  int i;
+  int ampoffseti=rint(ampoffset*4096.f);
+  int ampi=rint(amp*16.f);
+  long *ilsp=alloca(m*sizeof(*ilsp));
+  for(i=0;i<m;i++)ilsp[i]=vorbis_coslook_i(lsp[i]/M_PI*65536.f+.5f);
+
+  i=0;
+  while(i<n){
+    int j,k=map[i];
+    unsigned long pi=46341; /* 2**-.5 in 0.16 */
+    unsigned long qi=46341;
+    int qexp=0,shift;
+    long wi=vorbis_coslook_i(k*65536/ln);
+
+    qi*=labs(ilsp[0]-wi);
+    pi*=labs(ilsp[1]-wi);
+
+    for(j=3;j<m;j+=2){
+      if(!(shift=MLOOP_1[(pi|qi)>>25]))
+        if(!(shift=MLOOP_2[(pi|qi)>>19]))
+          shift=MLOOP_3[(pi|qi)>>16];
+      qi=(qi>>shift)*labs(ilsp[j-1]-wi);
+      pi=(pi>>shift)*labs(ilsp[j]-wi);
+      qexp+=shift;
+    }
+    if(!(shift=MLOOP_1[(pi|qi)>>25]))
+      if(!(shift=MLOOP_2[(pi|qi)>>19]))
+        shift=MLOOP_3[(pi|qi)>>16];
+
+    /* pi,qi normalized collectively, both tracked using qexp */
+
+    if(m&1){
+      /* odd order filter; slightly assymetric */
+      /* the last coefficient */
+      qi=(qi>>shift)*labs(ilsp[j-1]-wi);
+      pi=(pi>>shift)<<14;
+      qexp+=shift;
+
+      if(!(shift=MLOOP_1[(pi|qi)>>25]))
+        if(!(shift=MLOOP_2[(pi|qi)>>19]))
+          shift=MLOOP_3[(pi|qi)>>16];
+
+      pi>>=shift;
+      qi>>=shift;
+      qexp+=shift-14*((m+1)>>1);
+
+      pi=((pi*pi)>>16);
+      qi=((qi*qi)>>16);
+      qexp=qexp*2+m;
+
+      pi*=(1<<14)-((wi*wi)>>14);
+      qi+=pi>>14;
+
+    }else{
+      /* even order filter; still symmetric */
+
+      /* p*=p(1-w), q*=q(1+w), let normalization drift because it isn't
+         worth tracking step by step */
+
+      pi>>=shift;
+      qi>>=shift;
+      qexp+=shift-7*m;
+
+      pi=((pi*pi)>>16);
+      qi=((qi*qi)>>16);
+      qexp=qexp*2+m;
+
+      pi*=(1<<14)-wi;
+      qi*=(1<<14)+wi;
+      qi=(qi+pi)>>14;
+
+    }
+
+
+    /* we've let the normalization drift because it wasn't important;
+       however, for the lookup, things must be normalized again.  We
+       need at most one right shift or a number of left shifts */
+
+    if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */
+      qi>>=1; qexp++;
+    }else
+      while(qi && !(qi&0x8000)){ /* checks for 0.0xxxxxxxxxxxxxxx or less*/
+        qi<<=1; qexp--;
+      }
+
+    amp=vorbis_fromdBlook_i(ampi*                     /*  n.4         */
+                            vorbis_invsqlook_i(qi,qexp)-
+                                                      /*  m.8, m+n<=8 */
+                            ampoffseti);              /*  8.12[0]     */
+
+    curve[i]*=amp;
+    while(map[++i]==k)curve[i]*=amp;
+  }
+}
+
+#else
+
+/* old, nonoptimized but simple version for any poor sap who needs to
+   figure out what the hell this code does, or wants the other
+   fraction of a dB precision */
+
+/* side effect: changes *lsp to cosines of lsp */
+void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m,
+                            float amp,float ampoffset){
+  int i;
+  float wdel=M_PI/ln;
+  for(i=0;i<m;i++)lsp[i]=2.f*cos(lsp[i]);
+
+  i=0;
+  while(i<n){
+    int j,k=map[i];
+    float p=.5f;
+    float q=.5f;
+    float w=2.f*cos(wdel*k);
+    for(j=1;j<m;j+=2){
+      q *= w-lsp[j-1];
+      p *= w-lsp[j];
+    }
+    if(j==m){
+      /* odd order filter; slightly assymetric */
+      /* the last coefficient */
+      q*=w-lsp[j-1];
+      p*=p*(4.f-w*w);
+      q*=q;
+    }else{
+      /* even order filter; still symmetric */
+      p*=p*(2.f-w);
+      q*=q*(2.f+w);
+    }
+
+    q=fromdB(amp/sqrt(p+q)-ampoffset);
+
+    curve[i]*=q;
+    while(map[++i]==k)curve[i]*=q;
+  }
+}
+
+#endif
+#endif
+
+static void cheby(float *g, int ord) {
+  int i, j;
+
+  g[0] *= .5f;
+  for(i=2; i<= ord; i++) {
+    for(j=ord; j >= i; j--) {
+      g[j-2] -= g[j];
+      g[j] += g[j];
+    }
+  }
+}
+
+static int comp(const void *a,const void *b){
+  return (*(float *)a<*(float *)b)-(*(float *)a>*(float *)b);
+}
+
+/* Newton-Raphson-Maehly actually functioned as a decent root finder,
+   but there are root sets for which it gets into limit cycles
+   (exacerbated by zero suppression) and fails.  We can't afford to
+   fail, even if the failure is 1 in 100,000,000, so we now use
+   Laguerre and later polish with Newton-Raphson (which can then
+   afford to fail) */
+
+#define EPSILON 10e-7
+static int Laguerre_With_Deflation(float *a,int ord,float *r){
+  int i,m;
+  double lastdelta=0.f;
+  double *defl=alloca(sizeof(*defl)*(ord+1));
+  for(i=0;i<=ord;i++)defl[i]=a[i];
+
+  for(m=ord;m>0;m--){
+    double new=0.f,delta;
+
+    /* iterate a root */
+    while(1){
+      double p=defl[m],pp=0.f,ppp=0.f,denom;
+
+      /* eval the polynomial and its first two derivatives */
+      for(i=m;i>0;i--){
+        ppp = new*ppp + pp;
+        pp  = new*pp  + p;
+        p   = new*p   + defl[i-1];
+      }
+
+      /* Laguerre's method */
+      denom=(m-1) * ((m-1)*pp*pp - m*p*ppp);
+      if(denom<0)
+        return(-1);  /* complex root!  The LPC generator handed us a bad filter */
+
+      if(pp>0){
+        denom = pp + sqrt(denom);
+        if(denom<EPSILON)denom=EPSILON;
+      }else{
+        denom = pp - sqrt(denom);
+        if(denom>-(EPSILON))denom=-(EPSILON);
+      }
+
+      delta  = m*p/denom;
+      new   -= delta;
+
+      if(delta<0.f)delta*=-1;
+
+      if(fabs(delta/new)<10e-12)break;
+      lastdelta=delta;
+    }
+
+    r[m-1]=new;
+
+    /* forward deflation */
+
+    for(i=m;i>0;i--)
+      defl[i-1]+=new*defl[i];
+    defl++;
+
+  }
+  return(0);
+}
+
+
+/* for spit-and-polish only */
+static int Newton_Raphson(float *a,int ord,float *r){
+  int i, k, count=0;
+  double error=1.f;
+  double *root=alloca(ord*sizeof(*root));
+
+  for(i=0; i<ord;i++) root[i] = r[i];
+
+  while(error>1e-20){
+    error=0;
+
+    for(i=0; i<ord; i++) { /* Update each point. */
+      double pp=0.,delta;
+      double rooti=root[i];
+      double p=a[ord];
+      for(k=ord-1; k>= 0; k--) {
+
+        pp= pp* rooti + p;
+        p = p * rooti + a[k];
+      }
+
+      delta = p/pp;
+      root[i] -= delta;
+      error+= delta*delta;
+    }
+
+    if(count>40)return(-1);
+
+    count++;
+  }
+
+  /* Replaced the original bubble sort with a real sort.  With your
+     help, we can eliminate the bubble sort in our lifetime. --Monty */
+
+  for(i=0; i<ord;i++) r[i] = root[i];
+  return(0);
+}
+
+
+/* Convert lpc coefficients to lsp coefficients */
+int vorbis_lpc_to_lsp(float *lpc,float *lsp,int m){
+  int order2=(m+1)>>1;
+  int g1_order,g2_order;
+  float *g1=alloca(sizeof(*g1)*(order2+1));
+  float *g2=alloca(sizeof(*g2)*(order2+1));
+  float *g1r=alloca(sizeof(*g1r)*(order2+1));
+  float *g2r=alloca(sizeof(*g2r)*(order2+1));
+  int i;
+
+  /* even and odd are slightly different base cases */
+  g1_order=(m+1)>>1;
+  g2_order=(m)  >>1;
+
+  /* Compute the lengths of the x polynomials. */
+  /* Compute the first half of K & R F1 & F2 polynomials. */
+  /* Compute half of the symmetric and antisymmetric polynomials. */
+  /* Remove the roots at +1 and -1. */
+
+  g1[g1_order] = 1.f;
+  for(i=1;i<=g1_order;i++) g1[g1_order-i] = lpc[i-1]+lpc[m-i];
+  g2[g2_order] = 1.f;
+  for(i=1;i<=g2_order;i++) g2[g2_order-i] = lpc[i-1]-lpc[m-i];
+
+  if(g1_order>g2_order){
+    for(i=2; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+2];
+  }else{
+    for(i=1; i<=g1_order;i++) g1[g1_order-i] -= g1[g1_order-i+1];
+    for(i=1; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+1];
+  }
+
+  /* Convert into polynomials in cos(alpha) */
+  cheby(g1,g1_order);
+  cheby(g2,g2_order);
+
+  /* Find the roots of the 2 even polynomials.*/
+  if(Laguerre_With_Deflation(g1,g1_order,g1r) ||
+     Laguerre_With_Deflation(g2,g2_order,g2r))
+    return(-1);
+
+  Newton_Raphson(g1,g1_order,g1r); /* if it fails, it leaves g1r alone */
+  Newton_Raphson(g2,g2_order,g2r); /* if it fails, it leaves g2r alone */
+
+  qsort(g1r,g1_order,sizeof(*g1r),comp);
+  qsort(g2r,g2_order,sizeof(*g2r),comp);
+
+  for(i=0;i<g1_order;i++)
+    lsp[i*2] = acos(g1r[i]);
+
+  for(i=0;i<g2_order;i++)
+    lsp[i*2+1] = acos(g2r[i]);
+  return(0);
+}

+ 28 - 0
liboggvorbis/src/lsp.h

@@ -0,0 +1,28 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function: LSP (also called LSF) conversion routines
+  last mod: $Id: lsp.h 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+
+#ifndef _V_LSP_H_
+#define _V_LSP_H_
+
+extern int vorbis_lpc_to_lsp(float *lpc,float *lsp,int m);
+
+extern void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,
+                                float *lsp,int m,
+                                float amp,float ampoffset);
+
+#endif

+ 816 - 0
liboggvorbis/src/mapping0.c

@@ -0,0 +1,816 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: channel mapping 0 implementation
+ last mod: $Id: mapping0.c 17022 2010-03-25 03:45:42Z xiphmont $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+#include "codebook.h"
+#include "window.h"
+#include "registry.h"
+#include "psy.h"
+#include "misc.h"
+
+/* simplistic, wasteful way of doing this (unique lookup for each
+   mode/submapping); there should be a central repository for
+   identical lookups.  That will require minor work, so I'm putting it
+   off as low priority.
+
+   Why a lookup for each backend in a given mode?  Because the
+   blocksize is set by the mode, and low backend lookups may require
+   parameters from other areas of the mode/mapping */
+
+static void mapping0_free_info(vorbis_info_mapping *i){
+  vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i;
+  if(info){
+    memset(info,0,sizeof(*info));
+    _ogg_free(info);
+  }
+}
+
+static int ilog(unsigned int v){
+  int ret=0;
+  if(v)--v;
+  while(v){
+    ret++;
+    v>>=1;
+  }
+  return(ret);
+}
+
+static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm,
+                          oggpack_buffer *opb){
+  int i;
+  vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm;
+
+  /* another 'we meant to do it this way' hack...  up to beta 4, we
+     packed 4 binary zeros here to signify one submapping in use.  We
+     now redefine that to mean four bitflags that indicate use of
+     deeper features; bit0:submappings, bit1:coupling,
+     bit2,3:reserved. This is backward compatable with all actual uses
+     of the beta code. */
+
+  if(info->submaps>1){
+    oggpack_write(opb,1,1);
+    oggpack_write(opb,info->submaps-1,4);
+  }else
+    oggpack_write(opb,0,1);
+
+  if(info->coupling_steps>0){
+    oggpack_write(opb,1,1);
+    oggpack_write(opb,info->coupling_steps-1,8);
+
+    for(i=0;i<info->coupling_steps;i++){
+      oggpack_write(opb,info->coupling_mag[i],ilog(vi->channels));
+      oggpack_write(opb,info->coupling_ang[i],ilog(vi->channels));
+    }
+  }else
+    oggpack_write(opb,0,1);
+
+  oggpack_write(opb,0,2); /* 2,3:reserved */
+
+  /* we don't write the channel submappings if we only have one... */
+  if(info->submaps>1){
+    for(i=0;i<vi->channels;i++)
+      oggpack_write(opb,info->chmuxlist[i],4);
+  }
+  for(i=0;i<info->submaps;i++){
+    oggpack_write(opb,0,8); /* time submap unused */
+    oggpack_write(opb,info->floorsubmap[i],8);
+    oggpack_write(opb,info->residuesubmap[i],8);
+  }
+}
+
+/* also responsible for range checking */
+static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){
+  int i,b;
+  vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info));
+  codec_setup_info     *ci=vi->codec_setup;
+  memset(info,0,sizeof(*info));
+
+  b=oggpack_read(opb,1);
+  if(b<0)goto err_out;
+  if(b){
+    info->submaps=oggpack_read(opb,4)+1;
+    if(info->submaps<=0)goto err_out;
+  }else
+    info->submaps=1;
+
+  b=oggpack_read(opb,1);
+  if(b<0)goto err_out;
+  if(b){
+    info->coupling_steps=oggpack_read(opb,8)+1;
+    if(info->coupling_steps<=0)goto err_out;
+    for(i=0;i<info->coupling_steps;i++){
+      int testM=info->coupling_mag[i]=oggpack_read(opb,ilog(vi->channels));
+      int testA=info->coupling_ang[i]=oggpack_read(opb,ilog(vi->channels));
+
+      if(testM<0 ||
+         testA<0 ||
+         testM==testA ||
+         testM>=vi->channels ||
+         testA>=vi->channels) goto err_out;
+    }
+
+  }
+
+  if(oggpack_read(opb,2)!=0)goto err_out; /* 2,3:reserved */
+
+  if(info->submaps>1){
+    for(i=0;i<vi->channels;i++){
+      info->chmuxlist[i]=oggpack_read(opb,4);
+      if(info->chmuxlist[i]>=info->submaps || info->chmuxlist[i]<0)goto err_out;
+    }
+  }
+  for(i=0;i<info->submaps;i++){
+    oggpack_read(opb,8); /* time submap unused */
+    info->floorsubmap[i]=oggpack_read(opb,8);
+    if(info->floorsubmap[i]>=ci->floors || info->floorsubmap[i]<0)goto err_out;
+    info->residuesubmap[i]=oggpack_read(opb,8);
+    if(info->residuesubmap[i]>=ci->residues || info->residuesubmap[i]<0)goto err_out;
+  }
+
+  return info;
+
+ err_out:
+  mapping0_free_info(info);
+  return(NULL);
+}
+
+#include "os.h"
+#include "lpc.h"
+#include "lsp.h"
+#include "envelope.h"
+#include "mdct.h"
+#include "psy.h"
+#include "scales.h"
+
+#if 0
+static long seq=0;
+static ogg_int64_t total=0;
+static float FLOOR1_fromdB_LOOKUP[256]={
+  1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
+  1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
+  1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
+  2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
+  2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
+  3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
+  4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
+  6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
+  7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
+  1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
+  1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
+  1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
+  2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
+  2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
+  3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
+  4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
+  5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
+  7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
+  9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
+  1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
+  1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
+  2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
+  2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
+  3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
+  4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
+  5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
+  7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
+  9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
+  0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
+  0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
+  0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
+  0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
+  0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
+  0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
+  0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
+  0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
+  0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
+  0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
+  0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
+  0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
+  0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
+  0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
+  0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
+  0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
+  0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
+  0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
+  0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
+  0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
+  0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
+  0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
+  0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
+  0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
+  0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
+  0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
+  0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
+  0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
+  0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
+  0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
+  0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
+  0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
+  0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
+  0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
+  0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
+  0.82788260F, 0.88168307F, 0.9389798F, 1.F,
+};
+
+#endif
+
+
+static int mapping0_forward(vorbis_block *vb){
+  vorbis_dsp_state      *vd=vb->vd;
+  vorbis_info           *vi=vd->vi;
+  codec_setup_info      *ci=vi->codec_setup;
+  private_state         *b=vb->vd->backend_state;
+  vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
+  int                    n=vb->pcmend;
+  int i,j,k;
+
+  int    *nonzero    = alloca(sizeof(*nonzero)*vi->channels);
+  float  **gmdct     = _vorbis_block_alloc(vb,vi->channels*sizeof(*gmdct));
+  int    **iwork      = _vorbis_block_alloc(vb,vi->channels*sizeof(*iwork));
+  int ***floor_posts = _vorbis_block_alloc(vb,vi->channels*sizeof(*floor_posts));
+
+  float global_ampmax=vbi->ampmax;
+  float *local_ampmax=alloca(sizeof(*local_ampmax)*vi->channels);
+  int blocktype=vbi->blocktype;
+
+  int modenumber=vb->W;
+  vorbis_info_mapping0 *info=ci->map_param[modenumber];
+  vorbis_look_psy *psy_look=b->psy+blocktype+(vb->W?2:0);
+
+  vb->mode=modenumber;
+
+  for(i=0;i<vi->channels;i++){
+    float scale=4.f/n;
+    float scale_dB;
+
+    float *pcm     =vb->pcm[i];
+    float *logfft  =pcm;
+
+    iwork[i]=_vorbis_block_alloc(vb,n/2*sizeof(**iwork));
+    gmdct[i]=_vorbis_block_alloc(vb,n/2*sizeof(**gmdct));
+
+    scale_dB=todB(&scale) + .345; /* + .345 is a hack; the original
+                                     todB estimation used on IEEE 754
+                                     compliant machines had a bug that
+                                     returned dB values about a third
+                                     of a decibel too high.  The bug
+                                     was harmless because tunings
+                                     implicitly took that into
+                                     account.  However, fixing the bug
+                                     in the estimator requires
+                                     changing all the tunings as well.
+                                     For now, it's easier to sync
+                                     things back up here, and
+                                     recalibrate the tunings in the
+                                     next major model upgrade. */
+
+#if 0
+    if(vi->channels==2){
+      if(i==0)
+        _analysis_output("pcmL",seq,pcm,n,0,0,total-n/2);
+      else
+        _analysis_output("pcmR",seq,pcm,n,0,0,total-n/2);
+    }else{
+      _analysis_output("pcm",seq,pcm,n,0,0,total-n/2);
+    }
+#endif
+
+    /* window the PCM data */
+    _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW);
+
+#if 0
+    if(vi->channels==2){
+      if(i==0)
+        _analysis_output("windowedL",seq,pcm,n,0,0,total-n/2);
+      else
+        _analysis_output("windowedR",seq,pcm,n,0,0,total-n/2);
+    }else{
+      _analysis_output("windowed",seq,pcm,n,0,0,total-n/2);
+    }
+#endif
+
+    /* transform the PCM data */
+    /* only MDCT right now.... */
+    mdct_forward(b->transform[vb->W][0],pcm,gmdct[i]);
+
+    /* FFT yields more accurate tonal estimation (not phase sensitive) */
+    drft_forward(&b->fft_look[vb->W],pcm);
+    logfft[0]=scale_dB+todB(pcm)  + .345; /* + .345 is a hack; the
+                                     original todB estimation used on
+                                     IEEE 754 compliant machines had a
+                                     bug that returned dB values about
+                                     a third of a decibel too high.
+                                     The bug was harmless because
+                                     tunings implicitly took that into
+                                     account.  However, fixing the bug
+                                     in the estimator requires
+                                     changing all the tunings as well.
+                                     For now, it's easier to sync
+                                     things back up here, and
+                                     recalibrate the tunings in the
+                                     next major model upgrade. */
+    local_ampmax[i]=logfft[0];
+    for(j=1;j<n-1;j+=2){
+      float temp=pcm[j]*pcm[j]+pcm[j+1]*pcm[j+1];
+      temp=logfft[(j+1)>>1]=scale_dB+.5f*todB(&temp)  + .345; /* +
+                                     .345 is a hack; the original todB
+                                     estimation used on IEEE 754
+                                     compliant machines had a bug that
+                                     returned dB values about a third
+                                     of a decibel too high.  The bug
+                                     was harmless because tunings
+                                     implicitly took that into
+                                     account.  However, fixing the bug
+                                     in the estimator requires
+                                     changing all the tunings as well.
+                                     For now, it's easier to sync
+                                     things back up here, and
+                                     recalibrate the tunings in the
+                                     next major model upgrade. */
+      if(temp>local_ampmax[i])local_ampmax[i]=temp;
+    }
+
+    if(local_ampmax[i]>0.f)local_ampmax[i]=0.f;
+    if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i];
+
+#if 0
+    if(vi->channels==2){
+      if(i==0){
+        _analysis_output("fftL",seq,logfft,n/2,1,0,0);
+      }else{
+        _analysis_output("fftR",seq,logfft,n/2,1,0,0);
+      }
+    }else{
+      _analysis_output("fft",seq,logfft,n/2,1,0,0);
+    }
+#endif
+
+  }
+
+  {
+    float   *noise        = _vorbis_block_alloc(vb,n/2*sizeof(*noise));
+    float   *tone         = _vorbis_block_alloc(vb,n/2*sizeof(*tone));
+
+    for(i=0;i<vi->channels;i++){
+      /* the encoder setup assumes that all the modes used by any
+         specific bitrate tweaking use the same floor */
+
+      int submap=info->chmuxlist[i];
+
+      /* the following makes things clearer to *me* anyway */
+      float *mdct    =gmdct[i];
+      float *logfft  =vb->pcm[i];
+
+      float *logmdct =logfft+n/2;
+      float *logmask =logfft;
+
+      vb->mode=modenumber;
+
+      floor_posts[i]=_vorbis_block_alloc(vb,PACKETBLOBS*sizeof(**floor_posts));
+      memset(floor_posts[i],0,sizeof(**floor_posts)*PACKETBLOBS);
+
+      for(j=0;j<n/2;j++)
+        logmdct[j]=todB(mdct+j)  + .345; /* + .345 is a hack; the original
+                                     todB estimation used on IEEE 754
+                                     compliant machines had a bug that
+                                     returned dB values about a third
+                                     of a decibel too high.  The bug
+                                     was harmless because tunings
+                                     implicitly took that into
+                                     account.  However, fixing the bug
+                                     in the estimator requires
+                                     changing all the tunings as well.
+                                     For now, it's easier to sync
+                                     things back up here, and
+                                     recalibrate the tunings in the
+                                     next major model upgrade. */
+
+#if 0
+      if(vi->channels==2){
+        if(i==0)
+          _analysis_output("mdctL",seq,logmdct,n/2,1,0,0);
+        else
+          _analysis_output("mdctR",seq,logmdct,n/2,1,0,0);
+      }else{
+        _analysis_output("mdct",seq,logmdct,n/2,1,0,0);
+      }
+#endif
+
+      /* first step; noise masking.  Not only does 'noise masking'
+         give us curves from which we can decide how much resolution
+         to give noise parts of the spectrum, it also implicitly hands
+         us a tonality estimate (the larger the value in the
+         'noise_depth' vector, the more tonal that area is) */
+
+      _vp_noisemask(psy_look,
+                    logmdct,
+                    noise); /* noise does not have by-frequency offset
+                               bias applied yet */
+#if 0
+      if(vi->channels==2){
+        if(i==0)
+          _analysis_output("noiseL",seq,noise,n/2,1,0,0);
+        else
+          _analysis_output("noiseR",seq,noise,n/2,1,0,0);
+      }else{
+        _analysis_output("noise",seq,noise,n/2,1,0,0);
+      }
+#endif
+
+      /* second step: 'all the other crap'; all the stuff that isn't
+         computed/fit for bitrate management goes in the second psy
+         vector.  This includes tone masking, peak limiting and ATH */
+
+      _vp_tonemask(psy_look,
+                   logfft,
+                   tone,
+                   global_ampmax,
+                   local_ampmax[i]);
+
+#if 0
+      if(vi->channels==2){
+        if(i==0)
+          _analysis_output("toneL",seq,tone,n/2,1,0,0);
+        else
+          _analysis_output("toneR",seq,tone,n/2,1,0,0);
+      }else{
+        _analysis_output("tone",seq,tone,n/2,1,0,0);
+      }
+#endif
+
+      /* third step; we offset the noise vectors, overlay tone
+         masking.  We then do a floor1-specific line fit.  If we're
+         performing bitrate management, the line fit is performed
+         multiple times for up/down tweakage on demand. */
+
+#if 0
+      {
+      float aotuv[psy_look->n];
+#endif
+
+        _vp_offset_and_mix(psy_look,
+                           noise,
+                           tone,
+                           1,
+                           logmask,
+                           mdct,
+                           logmdct);
+
+#if 0
+        if(vi->channels==2){
+          if(i==0)
+            _analysis_output("aotuvM1_L",seq,aotuv,psy_look->n,1,1,0);
+          else
+            _analysis_output("aotuvM1_R",seq,aotuv,psy_look->n,1,1,0);
+        }else{
+          _analysis_output("aotuvM1",seq,aotuv,psy_look->n,1,1,0);
+        }
+      }
+#endif
+
+
+#if 0
+      if(vi->channels==2){
+        if(i==0)
+          _analysis_output("mask1L",seq,logmask,n/2,1,0,0);
+        else
+          _analysis_output("mask1R",seq,logmask,n/2,1,0,0);
+      }else{
+        _analysis_output("mask1",seq,logmask,n/2,1,0,0);
+      }
+#endif
+
+      /* this algorithm is hardwired to floor 1 for now; abort out if
+         we're *not* floor1.  This won't happen unless someone has
+         broken the encode setup lib.  Guard it anyway. */
+      if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1);
+
+      floor_posts[i][PACKETBLOBS/2]=
+        floor1_fit(vb,b->flr[info->floorsubmap[submap]],
+                   logmdct,
+                   logmask);
+
+      /* are we managing bitrate?  If so, perform two more fits for
+         later rate tweaking (fits represent hi/lo) */
+      if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){
+        /* higher rate by way of lower noise curve */
+
+        _vp_offset_and_mix(psy_look,
+                           noise,
+                           tone,
+                           2,
+                           logmask,
+                           mdct,
+                           logmdct);
+
+#if 0
+        if(vi->channels==2){
+          if(i==0)
+            _analysis_output("mask2L",seq,logmask,n/2,1,0,0);
+          else
+            _analysis_output("mask2R",seq,logmask,n/2,1,0,0);
+        }else{
+          _analysis_output("mask2",seq,logmask,n/2,1,0,0);
+        }
+#endif
+
+        floor_posts[i][PACKETBLOBS-1]=
+          floor1_fit(vb,b->flr[info->floorsubmap[submap]],
+                     logmdct,
+                     logmask);
+
+        /* lower rate by way of higher noise curve */
+        _vp_offset_and_mix(psy_look,
+                           noise,
+                           tone,
+                           0,
+                           logmask,
+                           mdct,
+                           logmdct);
+
+#if 0
+        if(vi->channels==2){
+          if(i==0)
+            _analysis_output("mask0L",seq,logmask,n/2,1,0,0);
+          else
+            _analysis_output("mask0R",seq,logmask,n/2,1,0,0);
+        }else{
+          _analysis_output("mask0",seq,logmask,n/2,1,0,0);
+        }
+#endif
+
+        floor_posts[i][0]=
+          floor1_fit(vb,b->flr[info->floorsubmap[submap]],
+                     logmdct,
+                     logmask);
+
+        /* we also interpolate a range of intermediate curves for
+           intermediate rates */
+        for(k=1;k<PACKETBLOBS/2;k++)
+          floor_posts[i][k]=
+            floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
+                                   floor_posts[i][0],
+                                   floor_posts[i][PACKETBLOBS/2],
+                                   k*65536/(PACKETBLOBS/2));
+        for(k=PACKETBLOBS/2+1;k<PACKETBLOBS-1;k++)
+          floor_posts[i][k]=
+            floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
+                                   floor_posts[i][PACKETBLOBS/2],
+                                   floor_posts[i][PACKETBLOBS-1],
+                                   (k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2));
+      }
+    }
+  }
+  vbi->ampmax=global_ampmax;
+
+  /*
+    the next phases are performed once for vbr-only and PACKETBLOB
+    times for bitrate managed modes.
+
+    1) encode actual mode being used
+    2) encode the floor for each channel, compute coded mask curve/res
+    3) normalize and couple.
+    4) encode residue
+    5) save packet bytes to the packetblob vector
+
+  */
+
+  /* iterate over the many masking curve fits we've created */
+
+  {
+    int **couple_bundle=alloca(sizeof(*couple_bundle)*vi->channels);
+    int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
+
+    for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2);
+        k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2);
+        k++){
+      oggpack_buffer *opb=vbi->packetblob[k];
+
+      /* start out our new packet blob with packet type and mode */
+      /* Encode the packet type */
+      oggpack_write(opb,0,1);
+      /* Encode the modenumber */
+      /* Encode frame mode, pre,post windowsize, then dispatch */
+      oggpack_write(opb,modenumber,b->modebits);
+      if(vb->W){
+        oggpack_write(opb,vb->lW,1);
+        oggpack_write(opb,vb->nW,1);
+      }
+
+      /* encode floor, compute masking curve, sep out residue */
+      for(i=0;i<vi->channels;i++){
+        int submap=info->chmuxlist[i];
+        int *ilogmask=iwork[i];
+
+        nonzero[i]=floor1_encode(opb,vb,b->flr[info->floorsubmap[submap]],
+                                 floor_posts[i][k],
+                                 ilogmask);
+#if 0
+        {
+          char buf[80];
+          sprintf(buf,"maskI%c%d",i?'R':'L',k);
+          float work[n/2];
+          for(j=0;j<n/2;j++)
+            work[j]=FLOOR1_fromdB_LOOKUP[iwork[i][j]];
+          _analysis_output(buf,seq,work,n/2,1,1,0);
+        }
+#endif
+      }
+
+      /* our iteration is now based on masking curve, not prequant and
+         coupling.  Only one prequant/coupling step */
+
+      /* quantize/couple */
+      /* incomplete implementation that assumes the tree is all depth
+         one, or no tree at all */
+      _vp_couple_quantize_normalize(k,
+                                    &ci->psy_g_param,
+                                    psy_look,
+                                    info,
+                                    gmdct,
+                                    iwork,
+                                    nonzero,
+                                    ci->psy_g_param.sliding_lowpass[vb->W][k],
+                                    vi->channels);
+
+#if 0
+      for(i=0;i<vi->channels;i++){
+        char buf[80];
+        sprintf(buf,"res%c%d",i?'R':'L',k);
+        float work[n/2];
+        for(j=0;j<n/2;j++)
+          work[j]=iwork[i][j];
+        _analysis_output(buf,seq,work,n/2,1,0,0);
+      }
+#endif
+
+      /* classify and encode by submap */
+      for(i=0;i<info->submaps;i++){
+        int ch_in_bundle=0;
+        long **classifications;
+        int resnum=info->residuesubmap[i];
+
+        for(j=0;j<vi->channels;j++){
+          if(info->chmuxlist[j]==i){
+            zerobundle[ch_in_bundle]=0;
+            if(nonzero[j])zerobundle[ch_in_bundle]=1;
+            couple_bundle[ch_in_bundle++]=iwork[j];
+          }
+        }
+
+        classifications=_residue_P[ci->residue_type[resnum]]->
+          class(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle);
+
+        ch_in_bundle=0;
+        for(j=0;j<vi->channels;j++)
+          if(info->chmuxlist[j]==i)
+            couple_bundle[ch_in_bundle++]=iwork[j];
+
+        _residue_P[ci->residue_type[resnum]]->
+          forward(opb,vb,b->residue[resnum],
+                  couple_bundle,zerobundle,ch_in_bundle,classifications,i);
+      }
+
+      /* ok, done encoding.  Next protopacket. */
+    }
+
+  }
+
+#if 0
+  seq++;
+  total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4;
+#endif
+  return(0);
+}
+
+static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){
+  vorbis_dsp_state     *vd=vb->vd;
+  vorbis_info          *vi=vd->vi;
+  codec_setup_info     *ci=vi->codec_setup;
+  private_state        *b=vd->backend_state;
+  vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l;
+
+  int                   i,j;
+  long                  n=vb->pcmend=ci->blocksizes[vb->W];
+
+  float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels);
+  int    *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
+
+  int   *nonzero  =alloca(sizeof(*nonzero)*vi->channels);
+  void **floormemo=alloca(sizeof(*floormemo)*vi->channels);
+
+  /* recover the spectral envelope; store it in the PCM vector for now */
+  for(i=0;i<vi->channels;i++){
+    int submap=info->chmuxlist[i];
+    floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]->
+      inverse1(vb,b->flr[info->floorsubmap[submap]]);
+    if(floormemo[i])
+      nonzero[i]=1;
+    else
+      nonzero[i]=0;
+    memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
+  }
+
+  /* channel coupling can 'dirty' the nonzero listing */
+  for(i=0;i<info->coupling_steps;i++){
+    if(nonzero[info->coupling_mag[i]] ||
+       nonzero[info->coupling_ang[i]]){
+      nonzero[info->coupling_mag[i]]=1;
+      nonzero[info->coupling_ang[i]]=1;
+    }
+  }
+
+  /* recover the residue into our working vectors */
+  for(i=0;i<info->submaps;i++){
+    int ch_in_bundle=0;
+    for(j=0;j<vi->channels;j++){
+      if(info->chmuxlist[j]==i){
+        if(nonzero[j])
+          zerobundle[ch_in_bundle]=1;
+        else
+          zerobundle[ch_in_bundle]=0;
+        pcmbundle[ch_in_bundle++]=vb->pcm[j];
+      }
+    }
+
+    _residue_P[ci->residue_type[info->residuesubmap[i]]]->
+      inverse(vb,b->residue[info->residuesubmap[i]],
+              pcmbundle,zerobundle,ch_in_bundle);
+  }
+
+  /* channel coupling */
+  for(i=info->coupling_steps-1;i>=0;i--){
+    float *pcmM=vb->pcm[info->coupling_mag[i]];
+    float *pcmA=vb->pcm[info->coupling_ang[i]];
+
+    for(j=0;j<n/2;j++){
+      float mag=pcmM[j];
+      float ang=pcmA[j];
+
+      if(mag>0)
+        if(ang>0){
+          pcmM[j]=mag;
+          pcmA[j]=mag-ang;
+        }else{
+          pcmA[j]=mag;
+          pcmM[j]=mag+ang;
+        }
+      else
+        if(ang>0){
+          pcmM[j]=mag;
+          pcmA[j]=mag+ang;
+        }else{
+          pcmA[j]=mag;
+          pcmM[j]=mag-ang;
+        }
+    }
+  }
+
+  /* compute and apply spectral envelope */
+  for(i=0;i<vi->channels;i++){
+    float *pcm=vb->pcm[i];
+    int submap=info->chmuxlist[i];
+    _floor_P[ci->floor_type[info->floorsubmap[submap]]]->
+      inverse2(vb,b->flr[info->floorsubmap[submap]],
+               floormemo[i],pcm);
+  }
+
+  /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
+  /* only MDCT right now.... */
+  for(i=0;i<vi->channels;i++){
+    float *pcm=vb->pcm[i];
+    mdct_backward(b->transform[vb->W][0],pcm,pcm);
+  }
+
+  /* all done! */
+  return(0);
+}
+
+/* export hooks */
+const vorbis_func_mapping mapping0_exportbundle={
+  &mapping0_pack,
+  &mapping0_unpack,
+  &mapping0_free_info,
+  &mapping0_forward,
+  &mapping0_inverse
+};

+ 785 - 0
liboggvorbis/src/masking.h

@@ -0,0 +1,785 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: masking curve data for psychoacoustics
+ last mod: $Id: masking.h 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _V_MASKING_H_
+#define _V_MASKING_H_
+
+/* more detailed ATH; the bass if flat to save stressing the floor
+   overly for only a bin or two of savings. */
+
+#define MAX_ATH 88
+static const float ATH[]={
+  /*15*/  -51, -52, -53, -54, -55, -56, -57, -58,
+  /*31*/  -59, -60, -61, -62, -63, -64, -65, -66,
+  /*63*/  -67, -68, -69, -70, -71, -72, -73, -74,
+  /*125*/ -75, -76, -77, -78, -80, -81, -82, -83,
+  /*250*/ -84, -85, -86, -87, -88, -88, -89, -89,
+  /*500*/ -90, -91, -91, -92, -93, -94, -95, -96,
+  /*1k*/  -96, -97, -98, -98, -99, -99,-100,-100,
+  /*2k*/ -101,-102,-103,-104,-106,-107,-107,-107,
+  /*4k*/ -107,-105,-103,-102,-101, -99, -98, -96,
+  /*8k*/  -95, -95, -96, -97, -96, -95, -93, -90,
+  /*16k*/ -80, -70, -50, -40, -30, -30, -30, -30
+};
+
+/* The tone masking curves from Ehmer's and Fielder's papers have been
+   replaced by an empirically collected data set.  The previously
+   published values were, far too often, simply on crack. */
+
+#define EHMER_OFFSET 16
+#define EHMER_MAX 56
+
+/* masking tones from -50 to 0dB, 62.5 through 16kHz at half octaves
+   test tones from -2 octaves to +5 octaves sampled at eighth octaves */
+/* (Vorbis 0dB, the loudest possible tone, is assumed to be ~100dB SPL
+   for collection of these curves) */
+
+static const float tonemasks[P_BANDS][6][EHMER_MAX]={
+  /* 62.5 Hz */
+  {{ -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,
+     -60,  -60,  -60,  -60,  -62,  -62,  -65,  -73,
+     -69,  -68,  -68,  -67,  -70,  -70,  -72,  -74,
+     -75,  -79,  -79,  -80,  -83,  -88,  -93, -100,
+     -110, -999, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   { -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
+     -48,  -48,  -48,  -48,  -48,  -53,  -61,  -66,
+     -66,  -68,  -67,  -70,  -76,  -76,  -72,  -73,
+     -75,  -76,  -78,  -79,  -83,  -88,  -93, -100,
+     -110, -999, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   { -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
+     -38,  -40,  -42,  -46,  -48,  -53,  -55,  -62,
+     -65,  -58,  -56,  -56,  -61,  -60,  -65,  -67,
+     -69,  -71,  -77,  -77,  -78,  -80,  -82,  -84,
+     -88,  -93,  -98, -106, -112, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   { -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
+     -25,  -26,  -27,  -29,  -32,  -38,  -48,  -52,
+     -52,  -50,  -48,  -48,  -51,  -52,  -54,  -60,
+     -67,  -67,  -66,  -68,  -69,  -73,  -73,  -76,
+     -80,  -81,  -81,  -85,  -85,  -86,  -88,  -93,
+     -100, -110, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   { -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,
+     -17,  -19,  -20,  -22,  -26,  -28,  -31,  -40,
+     -47,  -39,  -39,  -40,  -42,  -43,  -47,  -51,
+     -57,  -52,  -55,  -55,  -60,  -58,  -62,  -63,
+     -70,  -67,  -69,  -72,  -73,  -77,  -80,  -82,
+     -83,  -87,  -90,  -94,  -98, -104, -115, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   {  -8,   -8,   -8,   -8,   -8,   -8,   -8,   -8,
+      -8,   -8,  -10,  -11,  -15,  -19,  -25,  -30,
+      -34,  -31,  -30,  -31,  -29,  -32,  -35,  -42,
+      -48,  -42,  -44,  -46,  -50,  -50,  -51,  -52,
+      -59,  -54,  -55,  -55,  -58,  -62,  -63,  -66,
+      -72,  -73,  -76,  -75,  -78,  -80,  -80,  -81,
+      -84,  -88,  -90,  -94,  -98, -101, -106, -110}},
+  /* 88Hz */
+  {{ -66,  -66,  -66,  -66,  -66,  -66,  -66,  -66,
+     -66,  -66,  -66,  -66,  -66,  -67,  -67,  -67,
+     -76,  -72,  -71,  -74,  -76,  -76,  -75,  -78,
+     -79,  -79,  -81,  -83,  -86,  -89,  -93,  -97,
+     -100, -105, -110, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   { -47,  -47,  -47,  -47,  -47,  -47,  -47,  -47,
+     -47,  -47,  -47,  -48,  -51,  -55,  -59,  -66,
+     -66,  -66,  -67,  -66,  -68,  -69,  -70,  -74,
+     -79,  -77,  -77,  -78,  -80,  -81,  -82,  -84,
+     -86,  -88,  -91,  -95, -100, -108, -116, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   { -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+     -36,  -37,  -37,  -41,  -44,  -48,  -51,  -58,
+     -62,  -60,  -57,  -59,  -59,  -60,  -63,  -65,
+     -72,  -71,  -70,  -72,  -74,  -77,  -76,  -78,
+     -81,  -81,  -80,  -83,  -86,  -91,  -96, -100,
+     -105, -110, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   { -28,  -28,  -28,  -28,  -28,  -28,  -28,  -28,
+     -28,  -30,  -32,  -32,  -33,  -35,  -41,  -49,
+     -50,  -49,  -47,  -48,  -48,  -52,  -51,  -57,
+     -65,  -61,  -59,  -61,  -64,  -69,  -70,  -74,
+     -77,  -77,  -78,  -81,  -84,  -85,  -87,  -90,
+     -92,  -96, -100, -107, -112, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   { -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,
+     -20,  -21,  -23,  -27,  -30,  -35,  -36,  -41,
+     -46,  -44,  -42,  -40,  -41,  -41,  -43,  -48,
+     -55,  -53,  -52,  -53,  -56,  -59,  -58,  -60,
+     -67,  -66,  -69,  -71,  -72,  -75,  -79,  -81,
+     -84,  -87,  -90,  -93,  -97, -101, -107, -114,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   {  -9,   -9,   -9,   -9,   -9,   -9,   -9,   -9,
+      -11,  -12,  -12,  -15,  -16,  -20,  -23,  -30,
+      -37,  -34,  -33,  -34,  -31,  -32,  -32,  -38,
+      -47,  -44,  -41,  -40,  -47,  -49,  -46,  -46,
+      -58,  -50,  -50,  -54,  -58,  -62,  -64,  -67,
+      -67,  -70,  -72,  -76,  -79,  -83,  -87,  -91,
+      -96, -100, -104, -110, -999, -999, -999, -999}},
+  /* 125 Hz */
+  {{ -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,
+     -62,  -62,  -63,  -64,  -66,  -67,  -66,  -68,
+     -75,  -72,  -76,  -75,  -76,  -78,  -79,  -82,
+     -84,  -85,  -90,  -94, -101, -110, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   { -59,  -59,  -59,  -59,  -59,  -59,  -59,  -59,
+     -59,  -59,  -59,  -60,  -60,  -61,  -63,  -66,
+     -71,  -68,  -70,  -70,  -71,  -72,  -72,  -75,
+     -81,  -78,  -79,  -82,  -83,  -86,  -90,  -97,
+     -103, -113, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   { -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+     -53,  -54,  -55,  -57,  -56,  -57,  -55,  -61,
+     -65,  -60,  -60,  -62,  -63,  -63,  -66,  -68,
+     -74,  -73,  -75,  -75,  -78,  -80,  -80,  -82,
+     -85,  -90,  -96, -101, -108, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   { -46,  -46,  -46,  -46,  -46,  -46,  -46,  -46,
+     -46,  -46,  -47,  -47,  -47,  -47,  -48,  -51,
+     -57,  -51,  -49,  -50,  -51,  -53,  -54,  -59,
+     -66,  -60,  -62,  -67,  -67,  -70,  -72,  -75,
+     -76,  -78,  -81,  -85,  -88,  -94,  -97, -104,
+     -112, -999, -999, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   { -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+     -39,  -41,  -42,  -42,  -39,  -38,  -41,  -43,
+     -52,  -44,  -40,  -39,  -37,  -37,  -40,  -47,
+     -54,  -50,  -48,  -50,  -55,  -61,  -59,  -62,
+     -66,  -66,  -66,  -69,  -69,  -73,  -74,  -74,
+     -75,  -77,  -79,  -82,  -87,  -91,  -95, -100,
+     -108, -115, -999, -999, -999, -999, -999, -999},
+   { -28,  -26,  -24,  -22,  -20,  -20,  -23,  -29,
+     -30,  -31,  -28,  -27,  -28,  -28,  -28,  -35,
+     -40,  -33,  -32,  -29,  -30,  -30,  -30,  -37,
+     -45,  -41,  -37,  -38,  -45,  -47,  -47,  -48,
+     -53,  -49,  -48,  -50,  -49,  -49,  -51,  -52,
+     -58,  -56,  -57,  -56,  -60,  -61,  -62,  -70,
+     -72,  -74,  -78,  -83,  -88,  -93, -100, -106}},
+  /* 177 Hz */
+  {{-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -110, -105, -100,  -95,  -91,  -87,  -83,
+    -80,  -78,  -76,  -78,  -78,  -81,  -83,  -85,
+    -86,  -85,  -86,  -87,  -90,  -97, -107, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -110, -105, -100,  -95,  -90,
+    -85,  -81,  -77,  -73,  -70,  -67,  -67,  -68,
+    -75,  -73,  -70,  -69,  -70,  -72,  -75,  -79,
+    -84,  -83,  -84,  -86,  -88,  -89,  -89,  -93,
+    -98, -105, -112, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-105, -100,  -95,  -90,  -85,  -80,  -76,  -71,
+    -68,  -68,  -65,  -63,  -63,  -62,  -62,  -64,
+    -65,  -64,  -61,  -62,  -63,  -64,  -66,  -68,
+    -73,  -73,  -74,  -75,  -76,  -81,  -83,  -85,
+    -88,  -89,  -92,  -95, -100, -108, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   { -80,  -75,  -71,  -68,  -65,  -63,  -62,  -61,
+     -61,  -61,  -61,  -59,  -56,  -57,  -53,  -50,
+     -58,  -52,  -50,  -50,  -52,  -53,  -54,  -58,
+     -67,  -63,  -67,  -68,  -72,  -75,  -78,  -80,
+     -81,  -81,  -82,  -85,  -89,  -90,  -93,  -97,
+     -101, -107, -114, -999, -999, -999, -999, -999,
+     -999, -999, -999, -999, -999, -999, -999, -999},
+   { -65,  -61,  -59,  -57,  -56,  -55,  -55,  -56,
+     -56,  -57,  -55,  -53,  -52,  -47,  -44,  -44,
+     -50,  -44,  -41,  -39,  -39,  -42,  -40,  -46,
+     -51,  -49,  -50,  -53,  -54,  -63,  -60,  -61,
+     -62,  -66,  -66,  -66,  -70,  -73,  -74,  -75,
+     -76,  -75,  -79,  -85,  -89,  -91,  -96, -102,
+     -110, -999, -999, -999, -999, -999, -999, -999},
+   { -52,  -50,  -49,  -49,  -48,  -48,  -48,  -49,
+     -50,  -50,  -49,  -46,  -43,  -39,  -35,  -33,
+     -38,  -36,  -32,  -29,  -32,  -32,  -32,  -35,
+     -44,  -39,  -38,  -38,  -46,  -50,  -45,  -46,
+     -53,  -50,  -50,  -50,  -54,  -54,  -53,  -53,
+     -56,  -57,  -59,  -66,  -70,  -72,  -74,  -79,
+     -83,  -85,  -90, -97, -114, -999, -999, -999}},
+  /* 250 Hz */
+  {{-999, -999, -999, -999, -999, -999, -110, -105,
+    -100,  -95,  -90,  -86,  -80,  -75,  -75,  -79,
+    -80,  -79,  -80,  -81,  -82,  -88,  -95, -103,
+    -110, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -108, -103,  -98,  -93,
+    -88,  -83,  -79,  -78,  -75,  -71,  -67,  -68,
+    -73,  -73,  -72,  -73,  -75,  -77,  -80,  -82,
+    -88,  -93, -100, -107, -114, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -110, -105, -101,  -96,  -90,
+    -86,  -81,  -77,  -73,  -69,  -66,  -61,  -62,
+    -66,  -64,  -62,  -65,  -66,  -70,  -72,  -76,
+    -81,  -80,  -84,  -90,  -95, -102, -110, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -107, -103,  -97,  -92,  -88,
+    -83,  -79,  -74,  -70,  -66,  -59,  -53,  -58,
+    -62,  -55,  -54,  -54,  -54,  -58,  -61,  -62,
+    -72,  -70,  -72,  -75,  -78,  -80,  -81,  -80,
+    -83,  -83,  -88,  -93, -100, -107, -115, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -105, -100,  -95,  -90,  -85,
+    -80,  -75,  -70,  -66,  -62,  -56,  -48,  -44,
+    -48,  -46,  -46,  -43,  -46,  -48,  -48,  -51,
+    -58,  -58,  -59,  -60,  -62,  -62,  -61,  -61,
+    -65,  -64,  -65,  -68,  -70,  -74,  -75,  -78,
+    -81,  -86,  -95, -110, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999,  -999, -105, -100,  -95,  -90,  -85,  -80,
+    -75,  -70,  -65,  -61,  -55,  -49,  -39,  -33,
+    -40,  -35,  -32,  -38,  -40,  -33,  -35,  -37,
+    -46,  -41,  -45,  -44,  -46,  -42,  -45,  -46,
+    -52,  -50,  -50,  -50,  -54,  -54,  -55,  -57,
+    -62,  -64,  -66,  -68,  -70,  -76,  -81,  -90,
+    -100, -110, -999, -999, -999, -999, -999, -999}},
+  /* 354 hz */
+  {{-999, -999, -999, -999, -999, -999, -999, -999,
+    -105,  -98,  -90,  -85,  -82,  -83,  -80,  -78,
+    -84,  -79,  -80,  -83,  -87,  -89,  -91,  -93,
+    -99, -106, -117, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -105,  -98,  -90,  -85,  -80,  -75,  -70,  -68,
+    -74,  -72,  -74,  -77,  -80,  -82,  -85,  -87,
+    -92,  -89,  -91,  -95, -100, -106, -112, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -105,  -98,  -90,  -83,  -75,  -71,  -63,  -64,
+    -67,  -62,  -64,  -67,  -70,  -73,  -77,  -81,
+    -84,  -83,  -85,  -89,  -90,  -93,  -98, -104,
+    -109, -114, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -103,  -96,  -88,  -81,  -75,  -68,  -58,  -54,
+    -56,  -54,  -56,  -56,  -58,  -60,  -63,  -66,
+    -74,  -69,  -72,  -72,  -75,  -74,  -77,  -81,
+    -81,  -82,  -84,  -87,  -93,  -96,  -99, -104,
+    -110, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -108, -102,  -96,
+    -91,  -85,  -80,  -74,  -68,  -60,  -51,  -46,
+    -48,  -46,  -43,  -45,  -47,  -47,  -49,  -48,
+    -56,  -53,  -55,  -58,  -57,  -63,  -58,  -60,
+    -66,  -64,  -67,  -70,  -70,  -74,  -77,  -84,
+    -86,  -89,  -91,  -93,  -94, -101, -109, -118,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -108, -103,  -98,  -93,  -88,
+    -83,  -78,  -73,  -68,  -60,  -53,  -44,  -35,
+    -38,  -38,  -34,  -34,  -36,  -40,  -41,  -44,
+    -51,  -45,  -46,  -47,  -46,  -54,  -50,  -49,
+    -50,  -50,  -50,  -51,  -54,  -57,  -58,  -60,
+    -66,  -66,  -66,  -64,  -65,  -68,  -77,  -82,
+    -87,  -95, -110, -999, -999, -999, -999, -999}},
+  /* 500 Hz */
+  {{-999, -999, -999, -999, -999, -999, -999, -999,
+    -107, -102,  -97,  -92,  -87,  -83,  -78,  -75,
+    -82,  -79,  -83,  -85,  -89,  -92,  -95,  -98,
+    -101, -105, -109, -113, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -106,
+    -100,  -95,  -90,  -86,  -81,  -78,  -74,  -69,
+    -74,  -74,  -76,  -79,  -83,  -84,  -86,  -89,
+    -92,  -97,  -93, -100, -103, -107, -110, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -106, -100,
+    -95, -90, -87, -83, -80, -75, -69, -60,
+    -66, -66, -68, -70, -74, -78, -79, -81,
+    -81, -83, -84, -87, -93, -96, -99, -103,
+    -107, -110, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -108, -103, -98,
+    -93, -89, -85, -82, -78, -71, -62, -55,
+    -58, -58, -54, -54, -55, -59, -61, -62,
+    -70, -66, -66, -67, -70, -72, -75, -78,
+    -84, -84, -84, -88, -91, -90, -95, -98,
+    -102, -103, -106, -110, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -108, -103,  -98,  -94,
+    -90,  -87,  -82,  -79,  -73,  -67,  -58,  -47,
+    -50,  -45,  -41,  -45,  -48,  -44,  -44,  -49,
+    -54,  -51,  -48,  -47,  -49,  -50,  -51,  -57,
+    -58,  -60,  -63,  -69,  -70,  -69,  -71,  -74,
+    -78,  -82,  -90,  -95, -101, -105, -110, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -105, -101, -97, -93, -90,
+    -85, -80, -77, -72, -65, -56, -48, -37,
+    -40, -36, -34, -40, -50, -47, -38, -41,
+    -47, -38, -35, -39, -38, -43, -40, -45,
+    -50, -45, -44, -47, -50, -55, -48, -48,
+    -52, -66, -70, -76, -82, -90, -97, -105,
+    -110, -999, -999, -999, -999, -999, -999, -999}},
+  /* 707 Hz */
+  {{-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -108, -103,  -98,  -93,  -86,  -79,  -76,
+    -83,  -81,  -85,  -87,  -89,  -93,  -98, -102,
+    -107, -112, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -108, -103,  -98,  -93,  -86,  -79,  -71,
+    -77,  -74,  -77,  -79,  -81,  -84,  -85,  -90,
+    -92,  -93,  -92,  -98, -101, -108, -112, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -108, -103,  -98,  -93,  -87,  -78,  -68,  -65,
+    -66,  -62,  -65,  -67,  -70,  -73,  -75,  -78,
+    -82,  -82,  -83,  -84,  -91,  -93,  -98, -102,
+    -106, -110, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -105, -100, -95, -90, -82, -74, -62, -57,
+    -58, -56, -51, -52, -52, -54, -54, -58,
+    -66, -59, -60, -63, -66, -69, -73, -79,
+    -83, -84, -80, -81, -81, -82, -88, -92,
+    -98, -105, -113, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -107,
+    -102,  -97,  -92,  -84,  -79,  -69,  -57,  -47,
+    -52,  -47,  -44,  -45,  -50,  -52,  -42,  -42,
+    -53,  -43,  -43,  -48,  -51,  -56,  -55,  -52,
+    -57,  -59,  -61,  -62,  -67,  -71,  -78,  -83,
+    -86,  -94,  -98, -103, -110, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -105, -100,
+    -95,  -90,  -84,  -78,  -70,  -61,  -51,  -41,
+    -40,  -38,  -40,  -46,  -52,  -51,  -41,  -40,
+    -46,  -40,  -38,  -38,  -41,  -46,  -41,  -46,
+    -47,  -43,  -43,  -45,  -41,  -45,  -56,  -67,
+    -68,  -83,  -87,  -90,  -95, -102, -107, -113,
+    -999, -999, -999, -999, -999, -999, -999, -999}},
+  /* 1000 Hz */
+  {{-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -109, -105, -101,  -96,  -91,  -84,  -77,
+    -82,  -82,  -85,  -89,  -94, -100, -106, -110,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -106, -103,  -98,  -92,  -85,  -80,  -71,
+    -75,  -72,  -76,  -80,  -84,  -86,  -89,  -93,
+    -100, -107, -113, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -107,
+    -104, -101,  -97,  -92,  -88,  -84,  -80,  -64,
+    -66,  -63,  -64,  -66,  -69,  -73,  -77,  -83,
+    -83,  -86,  -91,  -98, -104, -111, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -107,
+    -104, -101,  -97,  -92,  -90,  -84,  -74,  -57,
+    -58,  -52,  -55,  -54,  -50,  -52,  -50,  -52,
+    -63,  -62,  -69,  -76,  -77,  -78,  -78,  -79,
+    -82,  -88,  -94, -100, -106, -111, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -106, -102,
+    -98,  -95,  -90,  -85,  -83,  -78,  -70,  -50,
+    -50,  -41,  -44,  -49,  -47,  -50,  -50,  -44,
+    -55,  -46,  -47,  -48,  -48,  -54,  -49,  -49,
+    -58,  -62,  -71,  -81,  -87,  -92,  -97, -102,
+    -108, -114, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -106, -102,
+    -98,  -95,  -90,  -85,  -83,  -78,  -70,  -45,
+    -43,  -41,  -47,  -50,  -51,  -50,  -49,  -45,
+    -47,  -41,  -44,  -41,  -39,  -43,  -38,  -37,
+    -40,  -41,  -44,  -50,  -58,  -65,  -73,  -79,
+    -85,  -92,  -97, -101, -105, -109, -113, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999}},
+  /* 1414 Hz */
+  {{-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -107, -100,  -95,  -87,  -81,
+    -85,  -83,  -88,  -93, -100, -107, -114, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -107, -101,  -95,  -88,  -83,  -76,
+    -73,  -72,  -79,  -84,  -90,  -95, -100, -105,
+    -110, -115, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -104,  -98,  -92,  -87,  -81,  -70,
+    -65,  -62,  -67,  -71,  -74,  -80,  -85,  -91,
+    -95,  -99, -103, -108, -111, -114, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -103,  -97,  -90,  -85,  -76,  -60,
+    -56,  -54,  -60,  -62,  -61,  -56,  -63,  -65,
+    -73,  -74,  -77,  -75,  -78,  -81,  -86,  -87,
+    -88,  -91,  -94,  -98, -103, -110, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -105,
+    -100,  -97,  -92,  -86,  -81,  -79,  -70,  -57,
+    -51,  -47,  -51,  -58,  -60,  -56,  -53,  -50,
+    -58,  -52,  -50,  -50,  -53,  -55,  -64,  -69,
+    -71,  -85,  -82,  -78,  -81,  -85,  -95, -102,
+    -112, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -105,
+    -100,  -97,  -92,  -85,  -83,  -79,  -72,  -49,
+    -40,  -43,  -43,  -54,  -56,  -51,  -50,  -40,
+    -43,  -38,  -36,  -35,  -37,  -38,  -37,  -44,
+    -54,  -60,  -57,  -60,  -70,  -75,  -84,  -92,
+    -103, -112, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999}},
+  /* 2000 Hz */
+  {{-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -110, -102,  -95,  -89,  -82,
+    -83,  -84,  -90,  -92,  -99, -107, -113, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -107, -101,  -95,  -89,  -83,  -72,
+    -74,  -78,  -85,  -88,  -88,  -90,  -92,  -98,
+    -105, -111, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -109, -103, -97, -93, -87, -81, -70,
+    -70, -67, -75, -73, -76, -79, -81, -83,
+    -88, -89, -97, -103, -110, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -107, -100,  -94,  -88,  -83,  -75,  -63,
+    -59,  -59,  -63,  -66,  -60,  -62,  -67,  -67,
+    -77,  -76,  -81,  -88,  -86,  -92,  -96, -102,
+    -109, -116, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -105,  -98,  -92,  -86,  -81,  -73,  -56,
+    -52,  -47,  -55,  -60,  -58,  -52,  -51,  -45,
+    -49,  -50,  -53,  -54,  -61,  -71,  -70,  -69,
+    -78,  -79,  -87,  -90,  -96, -104, -112, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -103,  -96,  -90,  -86,  -78,  -70,  -51,
+    -42,  -47,  -48,  -55,  -54,  -54,  -53,  -42,
+    -35,  -28,  -33,  -38,  -37,  -44,  -47,  -49,
+    -54,  -63,  -68,  -78,  -82,  -89,  -94,  -99,
+    -104, -109, -114, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999}},
+  /* 2828 Hz */
+  {{-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -110, -100,  -90,  -79,
+    -85,  -81,  -82,  -82,  -89,  -94,  -99, -103,
+    -109, -115, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -105,  -97,  -85,  -72,
+    -74,  -70,  -70,  -70,  -76,  -85,  -91,  -93,
+    -97, -103, -109, -115, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -112,  -93,  -81,  -68,
+    -62,  -60,  -60,  -57,  -63,  -70,  -77,  -82,
+    -90,  -93,  -98, -104, -109, -113, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -113, -100,  -93,  -84,  -63,
+    -58,  -48,  -53,  -54,  -52,  -52,  -57,  -64,
+    -66,  -76,  -83,  -81,  -85,  -85,  -90,  -95,
+    -98, -101, -103, -106, -108, -111, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -105,  -95,  -86,  -74,  -53,
+    -50,  -38,  -43,  -49,  -43,  -42,  -39,  -39,
+    -46,  -52,  -57,  -56,  -72,  -69,  -74,  -81,
+    -87,  -92,  -94,  -97,  -99, -102, -105, -108,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -108,  -99,  -90,  -76,  -66,  -45,
+    -43,  -41,  -44,  -47,  -43,  -47,  -40,  -30,
+    -31,  -31,  -39,  -33,  -40,  -41,  -43,  -53,
+    -59,  -70,  -73,  -77,  -79,  -82,  -84,  -87,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999}},
+  /* 4000 Hz */
+  {{-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -110,  -91,  -76,
+    -75,  -85,  -93,  -98, -104, -110, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -110,  -91,  -70,
+    -70,  -75,  -86,  -89,  -94,  -98, -101, -106,
+    -110, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -110,  -95,  -80,  -60,
+    -65,  -64,  -74,  -83,  -88,  -91,  -95,  -99,
+    -103, -107, -110, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -110,  -95,  -80,  -58,
+    -55,  -49,  -66,  -68,  -71,  -78,  -78,  -80,
+    -88,  -85,  -89,  -97, -100, -105, -110, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -110,  -95,  -80,  -53,
+    -52,  -41,  -59,  -59,  -49,  -58,  -56,  -63,
+    -86,  -79,  -90,  -93,  -98, -103, -107, -112,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -110,  -97,  -91,  -73,  -45,
+    -40,  -33,  -53,  -61,  -49,  -54,  -50,  -50,
+    -60,  -52,  -67,  -74,  -81,  -92,  -96, -100,
+    -105, -110, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999}},
+  /* 5657 Hz */
+  {{-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -113, -106,  -99,  -92,  -77,
+    -80,  -88,  -97, -106, -115, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -116, -109, -102,  -95,  -89,  -74,
+    -72,  -88,  -87,  -95, -102, -109, -116, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -116, -109, -102,  -95,  -89,  -75,
+    -66,  -74,  -77,  -78,  -86,  -87,  -90,  -96,
+    -105, -115, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -115, -108, -101,  -94,  -88,  -66,
+    -56,  -61,  -70,  -65,  -78,  -72,  -83,  -84,
+    -93,  -98, -105, -110, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -110, -105,  -95,  -89,  -82,  -57,
+    -52,  -52,  -59,  -56,  -59,  -58,  -69,  -67,
+    -88,  -82,  -82,  -89,  -94, -100, -108, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -110, -101,  -96,  -90,  -83,  -77,  -54,
+    -43,  -38,  -50,  -48,  -52,  -48,  -42,  -42,
+    -51,  -52,  -53,  -59,  -65,  -71,  -78,  -85,
+    -95, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999}},
+  /* 8000 Hz */
+  {{-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -120, -105,  -86,  -68,
+    -78,  -79,  -90, -100, -110, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -120, -105,  -86,  -66,
+    -73,  -77,  -88,  -96, -105, -115, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -120, -105,  -92,  -80,  -61,
+    -64,  -68,  -80,  -87,  -92, -100, -110, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -120, -104,  -91,  -79,  -52,
+    -60,  -54,  -64,  -69,  -77,  -80,  -82,  -84,
+    -85,  -87,  -88,  -90, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -118, -100,  -87,  -77,  -49,
+    -50,  -44,  -58,  -61,  -61,  -67,  -65,  -62,
+    -62,  -62,  -65,  -68, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -115,  -98,  -84,  -62,  -49,
+    -44,  -38,  -46,  -49,  -49,  -46,  -39,  -37,
+    -39,  -40,  -42,  -43, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999}},
+  /* 11314 Hz */
+  {{-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -110,  -88,  -74,
+    -77,  -82,  -82,  -85,  -90,  -94,  -99, -104,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -110,  -88,  -66,
+    -70,  -81,  -80,  -81,  -84,  -88,  -91,  -93,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -110,  -88,  -61,
+    -63,  -70,  -71,  -74,  -77,  -80,  -83,  -85,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -110, -86, -62,
+    -63,  -62,  -62,  -58,  -52,  -50,  -50,  -52,
+    -54, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -118, -108,  -84,  -53,
+    -50,  -50,  -50,  -55,  -47,  -45,  -40,  -40,
+    -40, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -118, -100,  -73,  -43,
+    -37,  -42,  -43,  -53,  -38,  -37,  -35,  -35,
+    -38, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999}},
+  /* 16000 Hz */
+  {{-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -110, -100,  -91,  -84,  -74,
+    -80,  -80,  -80,  -80,  -80, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -110, -100,  -91,  -84,  -74,
+    -68,  -68,  -68,  -68,  -68, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -110, -100,  -86,  -78,  -70,
+    -60,  -45,  -30,  -21, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -110, -100,  -87,  -78,  -67,
+    -48,  -38,  -29,  -21, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -110, -100,  -86,  -69,  -56,
+    -45,  -35,  -33,  -29, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999},
+   {-999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -110, -100,  -83,  -71,  -48,
+    -27,  -38,  -37,  -34, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999,
+    -999, -999, -999, -999, -999, -999, -999, -999}}
+};
+
+#endif

+ 563 - 0
liboggvorbis/src/mdct.c

@@ -0,0 +1,563 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: normalized modified discrete cosine transform
+           power of two length transform only [64 <= n ]
+ last mod: $Id: mdct.c 16227 2009-07-08 06:58:46Z xiphmont $
+
+ Original algorithm adapted long ago from _The use of multirate filter
+ banks for coding of high quality digital audio_, by T. Sporer,
+ K. Brandenburg and B. Edler, collection of the European Signal
+ Processing Conference (EUSIPCO), Amsterdam, June 1992, Vol.1, pp
+ 211-214
+
+ The below code implements an algorithm that no longer looks much like
+ that presented in the paper, but the basic structure remains if you
+ dig deep enough to see it.
+
+ This module DOES NOT INCLUDE code to generate/apply the window
+ function.  Everybody has their own weird favorite including me... I
+ happen to like the properties of y=sin(.5PI*sin^2(x)), but others may
+ vehemently disagree.
+
+ ********************************************************************/
+
+/* this can also be run as an integer transform by uncommenting a
+   define in mdct.h; the integerization is a first pass and although
+   it's likely stable for Vorbis, the dynamic range is constrained and
+   roundoff isn't done (so it's noisy).  Consider it functional, but
+   only a starting point.  There's no point on a machine with an FPU */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "vorbis/codec.h"
+#include "mdct.h"
+#include "os.h"
+#include "misc.h"
+
+/* build lookups for trig functions; also pre-figure scaling and
+   some window function algebra. */
+
+void mdct_init(mdct_lookup *lookup,int n){
+  int   *bitrev=_ogg_malloc(sizeof(*bitrev)*(n/4));
+  DATA_TYPE *T=_ogg_malloc(sizeof(*T)*(n+n/4));
+
+  int i;
+  int n2=n>>1;
+  int log2n=lookup->log2n=rint(log((float)n)/log(2.f));
+  lookup->n=n;
+  lookup->trig=T;
+  lookup->bitrev=bitrev;
+
+/* trig lookups... */
+
+  for(i=0;i<n/4;i++){
+    T[i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i)));
+    T[i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i)));
+    T[n2+i*2]=FLOAT_CONV(cos((M_PI/(2*n))*(2*i+1)));
+    T[n2+i*2+1]=FLOAT_CONV(sin((M_PI/(2*n))*(2*i+1)));
+  }
+  for(i=0;i<n/8;i++){
+    T[n+i*2]=FLOAT_CONV(cos((M_PI/n)*(4*i+2))*.5);
+    T[n+i*2+1]=FLOAT_CONV(-sin((M_PI/n)*(4*i+2))*.5);
+  }
+
+  /* bitreverse lookup... */
+
+  {
+    int mask=(1<<(log2n-1))-1,i,j;
+    int msb=1<<(log2n-2);
+    for(i=0;i<n/8;i++){
+      int acc=0;
+      for(j=0;msb>>j;j++)
+        if((msb>>j)&i)acc|=1<<j;
+      bitrev[i*2]=((~acc)&mask)-1;
+      bitrev[i*2+1]=acc;
+
+    }
+  }
+  lookup->scale=FLOAT_CONV(4.f/n);
+}
+
+/* 8 point butterfly (in place, 4 register) */
+STIN void mdct_butterfly_8(DATA_TYPE *x){
+  REG_TYPE r0   = x[6] + x[2];
+  REG_TYPE r1   = x[6] - x[2];
+  REG_TYPE r2   = x[4] + x[0];
+  REG_TYPE r3   = x[4] - x[0];
+
+           x[6] = r0   + r2;
+           x[4] = r0   - r2;
+
+           r0   = x[5] - x[1];
+           r2   = x[7] - x[3];
+           x[0] = r1   + r0;
+           x[2] = r1   - r0;
+
+           r0   = x[5] + x[1];
+           r1   = x[7] + x[3];
+           x[3] = r2   + r3;
+           x[1] = r2   - r3;
+           x[7] = r1   + r0;
+           x[5] = r1   - r0;
+
+}
+
+/* 16 point butterfly (in place, 4 register) */
+STIN void mdct_butterfly_16(DATA_TYPE *x){
+  REG_TYPE r0     = x[1]  - x[9];
+  REG_TYPE r1     = x[0]  - x[8];
+
+           x[8]  += x[0];
+           x[9]  += x[1];
+           x[0]   = MULT_NORM((r0   + r1) * cPI2_8);
+           x[1]   = MULT_NORM((r0   - r1) * cPI2_8);
+
+           r0     = x[3]  - x[11];
+           r1     = x[10] - x[2];
+           x[10] += x[2];
+           x[11] += x[3];
+           x[2]   = r0;
+           x[3]   = r1;
+
+           r0     = x[12] - x[4];
+           r1     = x[13] - x[5];
+           x[12] += x[4];
+           x[13] += x[5];
+           x[4]   = MULT_NORM((r0   - r1) * cPI2_8);
+           x[5]   = MULT_NORM((r0   + r1) * cPI2_8);
+
+           r0     = x[14] - x[6];
+           r1     = x[15] - x[7];
+           x[14] += x[6];
+           x[15] += x[7];
+           x[6]  = r0;
+           x[7]  = r1;
+
+           mdct_butterfly_8(x);
+           mdct_butterfly_8(x+8);
+}
+
+/* 32 point butterfly (in place, 4 register) */
+STIN void mdct_butterfly_32(DATA_TYPE *x){
+  REG_TYPE r0     = x[30] - x[14];
+  REG_TYPE r1     = x[31] - x[15];
+
+           x[30] +=         x[14];
+           x[31] +=         x[15];
+           x[14]  =         r0;
+           x[15]  =         r1;
+
+           r0     = x[28] - x[12];
+           r1     = x[29] - x[13];
+           x[28] +=         x[12];
+           x[29] +=         x[13];
+           x[12]  = MULT_NORM( r0 * cPI1_8  -  r1 * cPI3_8 );
+           x[13]  = MULT_NORM( r0 * cPI3_8  +  r1 * cPI1_8 );
+
+           r0     = x[26] - x[10];
+           r1     = x[27] - x[11];
+           x[26] +=         x[10];
+           x[27] +=         x[11];
+           x[10]  = MULT_NORM(( r0  - r1 ) * cPI2_8);
+           x[11]  = MULT_NORM(( r0  + r1 ) * cPI2_8);
+
+           r0     = x[24] - x[8];
+           r1     = x[25] - x[9];
+           x[24] += x[8];
+           x[25] += x[9];
+           x[8]   = MULT_NORM( r0 * cPI3_8  -  r1 * cPI1_8 );
+           x[9]   = MULT_NORM( r1 * cPI3_8  +  r0 * cPI1_8 );
+
+           r0     = x[22] - x[6];
+           r1     = x[7]  - x[23];
+           x[22] += x[6];
+           x[23] += x[7];
+           x[6]   = r1;
+           x[7]   = r0;
+
+           r0     = x[4]  - x[20];
+           r1     = x[5]  - x[21];
+           x[20] += x[4];
+           x[21] += x[5];
+           x[4]   = MULT_NORM( r1 * cPI1_8  +  r0 * cPI3_8 );
+           x[5]   = MULT_NORM( r1 * cPI3_8  -  r0 * cPI1_8 );
+
+           r0     = x[2]  - x[18];
+           r1     = x[3]  - x[19];
+           x[18] += x[2];
+           x[19] += x[3];
+           x[2]   = MULT_NORM(( r1  + r0 ) * cPI2_8);
+           x[3]   = MULT_NORM(( r1  - r0 ) * cPI2_8);
+
+           r0     = x[0]  - x[16];
+           r1     = x[1]  - x[17];
+           x[16] += x[0];
+           x[17] += x[1];
+           x[0]   = MULT_NORM( r1 * cPI3_8  +  r0 * cPI1_8 );
+           x[1]   = MULT_NORM( r1 * cPI1_8  -  r0 * cPI3_8 );
+
+           mdct_butterfly_16(x);
+           mdct_butterfly_16(x+16);
+
+}
+
+/* N point first stage butterfly (in place, 2 register) */
+STIN void mdct_butterfly_first(DATA_TYPE *T,
+                                        DATA_TYPE *x,
+                                        int points){
+
+  DATA_TYPE *x1        = x          + points      - 8;
+  DATA_TYPE *x2        = x          + (points>>1) - 8;
+  REG_TYPE   r0;
+  REG_TYPE   r1;
+
+  do{
+
+               r0      = x1[6]      -  x2[6];
+               r1      = x1[7]      -  x2[7];
+               x1[6]  += x2[6];
+               x1[7]  += x2[7];
+               x2[6]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
+               x2[7]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
+
+               r0      = x1[4]      -  x2[4];
+               r1      = x1[5]      -  x2[5];
+               x1[4]  += x2[4];
+               x1[5]  += x2[5];
+               x2[4]   = MULT_NORM(r1 * T[5]  +  r0 * T[4]);
+               x2[5]   = MULT_NORM(r1 * T[4]  -  r0 * T[5]);
+
+               r0      = x1[2]      -  x2[2];
+               r1      = x1[3]      -  x2[3];
+               x1[2]  += x2[2];
+               x1[3]  += x2[3];
+               x2[2]   = MULT_NORM(r1 * T[9]  +  r0 * T[8]);
+               x2[3]   = MULT_NORM(r1 * T[8]  -  r0 * T[9]);
+
+               r0      = x1[0]      -  x2[0];
+               r1      = x1[1]      -  x2[1];
+               x1[0]  += x2[0];
+               x1[1]  += x2[1];
+               x2[0]   = MULT_NORM(r1 * T[13] +  r0 * T[12]);
+               x2[1]   = MULT_NORM(r1 * T[12] -  r0 * T[13]);
+
+    x1-=8;
+    x2-=8;
+    T+=16;
+
+  }while(x2>=x);
+}
+
+/* N/stage point generic N stage butterfly (in place, 2 register) */
+STIN void mdct_butterfly_generic(DATA_TYPE *T,
+                                          DATA_TYPE *x,
+                                          int points,
+                                          int trigint){
+
+  DATA_TYPE *x1        = x          + points      - 8;
+  DATA_TYPE *x2        = x          + (points>>1) - 8;
+  REG_TYPE   r0;
+  REG_TYPE   r1;
+
+  do{
+
+               r0      = x1[6]      -  x2[6];
+               r1      = x1[7]      -  x2[7];
+               x1[6]  += x2[6];
+               x1[7]  += x2[7];
+               x2[6]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
+               x2[7]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
+
+               T+=trigint;
+
+               r0      = x1[4]      -  x2[4];
+               r1      = x1[5]      -  x2[5];
+               x1[4]  += x2[4];
+               x1[5]  += x2[5];
+               x2[4]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
+               x2[5]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
+
+               T+=trigint;
+
+               r0      = x1[2]      -  x2[2];
+               r1      = x1[3]      -  x2[3];
+               x1[2]  += x2[2];
+               x1[3]  += x2[3];
+               x2[2]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
+               x2[3]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
+
+               T+=trigint;
+
+               r0      = x1[0]      -  x2[0];
+               r1      = x1[1]      -  x2[1];
+               x1[0]  += x2[0];
+               x1[1]  += x2[1];
+               x2[0]   = MULT_NORM(r1 * T[1]  +  r0 * T[0]);
+               x2[1]   = MULT_NORM(r1 * T[0]  -  r0 * T[1]);
+
+               T+=trigint;
+    x1-=8;
+    x2-=8;
+
+  }while(x2>=x);
+}
+
+STIN void mdct_butterflies(mdct_lookup *init,
+                             DATA_TYPE *x,
+                             int points){
+
+  DATA_TYPE *T=init->trig;
+  int stages=init->log2n-5;
+  int i,j;
+
+  if(--stages>0){
+    mdct_butterfly_first(T,x,points);
+  }
+
+  for(i=1;--stages>0;i++){
+    for(j=0;j<(1<<i);j++)
+      mdct_butterfly_generic(T,x+(points>>i)*j,points>>i,4<<i);
+  }
+
+  for(j=0;j<points;j+=32)
+    mdct_butterfly_32(x+j);
+
+}
+
+void mdct_clear(mdct_lookup *l){
+  if(l){
+    if(l->trig)_ogg_free(l->trig);
+    if(l->bitrev)_ogg_free(l->bitrev);
+    memset(l,0,sizeof(*l));
+  }
+}
+
+STIN void mdct_bitreverse(mdct_lookup *init,
+                            DATA_TYPE *x){
+  int        n       = init->n;
+  int       *bit     = init->bitrev;
+  DATA_TYPE *w0      = x;
+  DATA_TYPE *w1      = x = w0+(n>>1);
+  DATA_TYPE *T       = init->trig+n;
+
+  do{
+    DATA_TYPE *x0    = x+bit[0];
+    DATA_TYPE *x1    = x+bit[1];
+
+    REG_TYPE  r0     = x0[1]  - x1[1];
+    REG_TYPE  r1     = x0[0]  + x1[0];
+    REG_TYPE  r2     = MULT_NORM(r1     * T[0]   + r0 * T[1]);
+    REG_TYPE  r3     = MULT_NORM(r1     * T[1]   - r0 * T[0]);
+
+              w1    -= 4;
+
+              r0     = HALVE(x0[1] + x1[1]);
+              r1     = HALVE(x0[0] - x1[0]);
+
+              w0[0]  = r0     + r2;
+              w1[2]  = r0     - r2;
+              w0[1]  = r1     + r3;
+              w1[3]  = r3     - r1;
+
+              x0     = x+bit[2];
+              x1     = x+bit[3];
+
+              r0     = x0[1]  - x1[1];
+              r1     = x0[0]  + x1[0];
+              r2     = MULT_NORM(r1     * T[2]   + r0 * T[3]);
+              r3     = MULT_NORM(r1     * T[3]   - r0 * T[2]);
+
+              r0     = HALVE(x0[1] + x1[1]);
+              r1     = HALVE(x0[0] - x1[0]);
+
+              w0[2]  = r0     + r2;
+              w1[0]  = r0     - r2;
+              w0[3]  = r1     + r3;
+              w1[1]  = r3     - r1;
+
+              T     += 4;
+              bit   += 4;
+              w0    += 4;
+
+  }while(w0<w1);
+}
+
+void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
+  int n=init->n;
+  int n2=n>>1;
+  int n4=n>>2;
+
+  /* rotate */
+
+  DATA_TYPE *iX = in+n2-7;
+  DATA_TYPE *oX = out+n2+n4;
+  DATA_TYPE *T  = init->trig+n4;
+
+  do{
+    oX         -= 4;
+    oX[0]       = MULT_NORM(-iX[2] * T[3] - iX[0]  * T[2]);
+    oX[1]       = MULT_NORM (iX[0] * T[3] - iX[2]  * T[2]);
+    oX[2]       = MULT_NORM(-iX[6] * T[1] - iX[4]  * T[0]);
+    oX[3]       = MULT_NORM (iX[4] * T[1] - iX[6]  * T[0]);
+    iX         -= 8;
+    T          += 4;
+  }while(iX>=in);
+
+  iX            = in+n2-8;
+  oX            = out+n2+n4;
+  T             = init->trig+n4;
+
+  do{
+    T          -= 4;
+    oX[0]       =  MULT_NORM (iX[4] * T[3] + iX[6] * T[2]);
+    oX[1]       =  MULT_NORM (iX[4] * T[2] - iX[6] * T[3]);
+    oX[2]       =  MULT_NORM (iX[0] * T[1] + iX[2] * T[0]);
+    oX[3]       =  MULT_NORM (iX[0] * T[0] - iX[2] * T[1]);
+    iX         -= 8;
+    oX         += 4;
+  }while(iX>=in);
+
+  mdct_butterflies(init,out+n2,n2);
+  mdct_bitreverse(init,out);
+
+  /* roatate + window */
+
+  {
+    DATA_TYPE *oX1=out+n2+n4;
+    DATA_TYPE *oX2=out+n2+n4;
+    DATA_TYPE *iX =out;
+    T             =init->trig+n2;
+
+    do{
+      oX1-=4;
+
+      oX1[3]  =  MULT_NORM (iX[0] * T[1] - iX[1] * T[0]);
+      oX2[0]  = -MULT_NORM (iX[0] * T[0] + iX[1] * T[1]);
+
+      oX1[2]  =  MULT_NORM (iX[2] * T[3] - iX[3] * T[2]);
+      oX2[1]  = -MULT_NORM (iX[2] * T[2] + iX[3] * T[3]);
+
+      oX1[1]  =  MULT_NORM (iX[4] * T[5] - iX[5] * T[4]);
+      oX2[2]  = -MULT_NORM (iX[4] * T[4] + iX[5] * T[5]);
+
+      oX1[0]  =  MULT_NORM (iX[6] * T[7] - iX[7] * T[6]);
+      oX2[3]  = -MULT_NORM (iX[6] * T[6] + iX[7] * T[7]);
+
+      oX2+=4;
+      iX    +=   8;
+      T     +=   8;
+    }while(iX<oX1);
+
+    iX=out+n2+n4;
+    oX1=out+n4;
+    oX2=oX1;
+
+    do{
+      oX1-=4;
+      iX-=4;
+
+      oX2[0] = -(oX1[3] = iX[3]);
+      oX2[1] = -(oX1[2] = iX[2]);
+      oX2[2] = -(oX1[1] = iX[1]);
+      oX2[3] = -(oX1[0] = iX[0]);
+
+      oX2+=4;
+    }while(oX2<iX);
+
+    iX=out+n2+n4;
+    oX1=out+n2+n4;
+    oX2=out+n2;
+    do{
+      oX1-=4;
+      oX1[0]= iX[3];
+      oX1[1]= iX[2];
+      oX1[2]= iX[1];
+      oX1[3]= iX[0];
+      iX+=4;
+    }while(oX1>oX2);
+  }
+}
+
+void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out){
+  int n=init->n;
+  int n2=n>>1;
+  int n4=n>>2;
+  int n8=n>>3;
+  DATA_TYPE *w=alloca(n*sizeof(*w)); /* forward needs working space */
+  DATA_TYPE *w2=w+n2;
+
+  /* rotate */
+
+  /* window + rotate + step 1 */
+
+  REG_TYPE r0;
+  REG_TYPE r1;
+  DATA_TYPE *x0=in+n2+n4;
+  DATA_TYPE *x1=x0+1;
+  DATA_TYPE *T=init->trig+n2;
+
+  int i=0;
+
+  for(i=0;i<n8;i+=2){
+    x0 -=4;
+    T-=2;
+    r0= x0[2] + x1[0];
+    r1= x0[0] + x1[2];
+    w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
+    w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
+    x1 +=4;
+  }
+
+  x1=in+1;
+
+  for(;i<n2-n8;i+=2){
+    T-=2;
+    x0 -=4;
+    r0= x0[2] - x1[0];
+    r1= x0[0] - x1[2];
+    w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
+    w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
+    x1 +=4;
+  }
+
+  x0=in+n;
+
+  for(;i<n2;i+=2){
+    T-=2;
+    x0 -=4;
+    r0= -x0[2] - x1[0];
+    r1= -x0[0] - x1[2];
+    w2[i]=   MULT_NORM(r1*T[1] + r0*T[0]);
+    w2[i+1]= MULT_NORM(r1*T[0] - r0*T[1]);
+    x1 +=4;
+  }
+
+
+  mdct_butterflies(init,w+n2,n2);
+  mdct_bitreverse(init,w);
+
+  /* roatate + window */
+
+  T=init->trig+n2;
+  x0=out+n2;
+
+  for(i=0;i<n4;i++){
+    x0--;
+    out[i] =MULT_NORM((w[0]*T[0]+w[1]*T[1])*init->scale);
+    x0[0]  =MULT_NORM((w[0]*T[1]-w[1]*T[0])*init->scale);
+    w+=2;
+    T+=2;
+  }
+}

+ 71 - 0
liboggvorbis/src/mdct.h

@@ -0,0 +1,71 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: modified discrete cosine transform prototypes
+ last mod: $Id: mdct.h 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _OGG_mdct_H_
+#define _OGG_mdct_H_
+
+#include "vorbis/codec.h"
+
+
+
+
+
+/*#define MDCT_INTEGERIZED  <- be warned there could be some hurt left here*/
+#ifdef MDCT_INTEGERIZED
+
+#define DATA_TYPE int
+#define REG_TYPE  register int
+#define TRIGBITS 14
+#define cPI3_8 6270
+#define cPI2_8 11585
+#define cPI1_8 15137
+
+#define FLOAT_CONV(x) ((int)((x)*(1<<TRIGBITS)+.5))
+#define MULT_NORM(x) ((x)>>TRIGBITS)
+#define HALVE(x) ((x)>>1)
+
+#else
+
+#define DATA_TYPE float
+#define REG_TYPE  float
+#define cPI3_8 .38268343236508977175F
+#define cPI2_8 .70710678118654752441F
+#define cPI1_8 .92387953251128675613F
+
+#define FLOAT_CONV(x) (x)
+#define MULT_NORM(x) (x)
+#define HALVE(x) ((x)*.5f)
+
+#endif
+
+
+typedef struct {
+  int n;
+  int log2n;
+
+  DATA_TYPE *trig;
+  int       *bitrev;
+
+  DATA_TYPE scale;
+} mdct_lookup;
+
+extern void mdct_init(mdct_lookup *lookup,int n);
+extern void mdct_clear(mdct_lookup *l);
+extern void mdct_forward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out);
+extern void mdct_backward(mdct_lookup *init, DATA_TYPE *in, DATA_TYPE *out);
+
+#endif

+ 57 - 0
liboggvorbis/src/misc.h

@@ -0,0 +1,57 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: miscellaneous prototypes
+ last mod: $Id: misc.h 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _V_RANDOM_H_
+#define _V_RANDOM_H_
+#include "vorbis/codec.h"
+
+extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes);
+extern void _vorbis_block_ripcord(vorbis_block *vb);
+
+#ifdef ANALYSIS
+extern int analysis_noisy;
+extern void _analysis_output(char *base,int i,float *v,int n,int bark,int dB,
+                             ogg_int64_t off);
+extern void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,
+                             ogg_int64_t off);
+#endif
+
+#ifdef DEBUG_MALLOC
+
+#define _VDBG_GRAPHFILE "malloc.m"
+#undef _VDBG_GRAPHFILE
+extern void *_VDBG_malloc(void *ptr,long bytes,char *file,long line);
+extern void _VDBG_free(void *ptr,char *file,long line);
+
+#ifndef MISC_C
+#undef _ogg_malloc
+#undef _ogg_calloc
+#undef _ogg_realloc
+#undef _ogg_free
+
+#define _ogg_malloc(x) _VDBG_malloc(NULL,(x),__FILE__,__LINE__)
+#define _ogg_calloc(x,y) _VDBG_malloc(NULL,(x)*(y),__FILE__,__LINE__)
+#define _ogg_realloc(x,y) _VDBG_malloc((x),(y),__FILE__,__LINE__)
+#define _ogg_free(x) _VDBG_free((x),__FILE__,__LINE__)
+#endif
+#endif
+
+#endif
+
+
+
+

+ 260 - 0
liboggvorbis/src/modes/floor_all.h

@@ -0,0 +1,260 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: key floor settings
+ last mod: $Id: floor_all.h 17050 2010-03-26 01:34:42Z xiphmont $
+
+ ********************************************************************/
+
+#include "vorbis/codec.h"
+#include "backends.h"
+#include "books/floor/floor_books.h"
+
+static const static_codebook*const _floor_128x4_books[]={
+  &_huff_book_line_128x4_class0,
+  &_huff_book_line_128x4_0sub0,
+  &_huff_book_line_128x4_0sub1,
+  &_huff_book_line_128x4_0sub2,
+  &_huff_book_line_128x4_0sub3,
+};
+static const static_codebook*const _floor_256x4_books[]={
+  &_huff_book_line_256x4_class0,
+  &_huff_book_line_256x4_0sub0,
+  &_huff_book_line_256x4_0sub1,
+  &_huff_book_line_256x4_0sub2,
+  &_huff_book_line_256x4_0sub3,
+};
+static const static_codebook*const _floor_128x7_books[]={
+  &_huff_book_line_128x7_class0,
+  &_huff_book_line_128x7_class1,
+
+  &_huff_book_line_128x7_0sub1,
+  &_huff_book_line_128x7_0sub2,
+  &_huff_book_line_128x7_0sub3,
+  &_huff_book_line_128x7_1sub1,
+  &_huff_book_line_128x7_1sub2,
+  &_huff_book_line_128x7_1sub3,
+};
+static const static_codebook*const _floor_256x7_books[]={
+  &_huff_book_line_256x7_class0,
+  &_huff_book_line_256x7_class1,
+
+  &_huff_book_line_256x7_0sub1,
+  &_huff_book_line_256x7_0sub2,
+  &_huff_book_line_256x7_0sub3,
+  &_huff_book_line_256x7_1sub1,
+  &_huff_book_line_256x7_1sub2,
+  &_huff_book_line_256x7_1sub3,
+};
+static const static_codebook*const _floor_128x11_books[]={
+  &_huff_book_line_128x11_class1,
+  &_huff_book_line_128x11_class2,
+  &_huff_book_line_128x11_class3,
+
+  &_huff_book_line_128x11_0sub0,
+  &_huff_book_line_128x11_1sub0,
+  &_huff_book_line_128x11_1sub1,
+  &_huff_book_line_128x11_2sub1,
+  &_huff_book_line_128x11_2sub2,
+  &_huff_book_line_128x11_2sub3,
+  &_huff_book_line_128x11_3sub1,
+  &_huff_book_line_128x11_3sub2,
+  &_huff_book_line_128x11_3sub3,
+};
+static const static_codebook*const _floor_128x17_books[]={
+  &_huff_book_line_128x17_class1,
+  &_huff_book_line_128x17_class2,
+  &_huff_book_line_128x17_class3,
+
+  &_huff_book_line_128x17_0sub0,
+  &_huff_book_line_128x17_1sub0,
+  &_huff_book_line_128x17_1sub1,
+  &_huff_book_line_128x17_2sub1,
+  &_huff_book_line_128x17_2sub2,
+  &_huff_book_line_128x17_2sub3,
+  &_huff_book_line_128x17_3sub1,
+  &_huff_book_line_128x17_3sub2,
+  &_huff_book_line_128x17_3sub3,
+};
+static const static_codebook*const _floor_256x4low_books[]={
+  &_huff_book_line_256x4low_class0,
+  &_huff_book_line_256x4low_0sub0,
+  &_huff_book_line_256x4low_0sub1,
+  &_huff_book_line_256x4low_0sub2,
+  &_huff_book_line_256x4low_0sub3,
+};
+static const static_codebook*const _floor_1024x27_books[]={
+  &_huff_book_line_1024x27_class1,
+  &_huff_book_line_1024x27_class2,
+  &_huff_book_line_1024x27_class3,
+  &_huff_book_line_1024x27_class4,
+
+  &_huff_book_line_1024x27_0sub0,
+  &_huff_book_line_1024x27_1sub0,
+  &_huff_book_line_1024x27_1sub1,
+  &_huff_book_line_1024x27_2sub0,
+  &_huff_book_line_1024x27_2sub1,
+  &_huff_book_line_1024x27_3sub1,
+  &_huff_book_line_1024x27_3sub2,
+  &_huff_book_line_1024x27_3sub3,
+  &_huff_book_line_1024x27_4sub1,
+  &_huff_book_line_1024x27_4sub2,
+  &_huff_book_line_1024x27_4sub3,
+};
+static const static_codebook*const _floor_2048x27_books[]={
+  &_huff_book_line_2048x27_class1,
+  &_huff_book_line_2048x27_class2,
+  &_huff_book_line_2048x27_class3,
+  &_huff_book_line_2048x27_class4,
+
+  &_huff_book_line_2048x27_0sub0,
+  &_huff_book_line_2048x27_1sub0,
+  &_huff_book_line_2048x27_1sub1,
+  &_huff_book_line_2048x27_2sub0,
+  &_huff_book_line_2048x27_2sub1,
+  &_huff_book_line_2048x27_3sub1,
+  &_huff_book_line_2048x27_3sub2,
+  &_huff_book_line_2048x27_3sub3,
+  &_huff_book_line_2048x27_4sub1,
+  &_huff_book_line_2048x27_4sub2,
+  &_huff_book_line_2048x27_4sub3,
+};
+
+static const static_codebook*const _floor_512x17_books[]={
+  &_huff_book_line_512x17_class1,
+  &_huff_book_line_512x17_class2,
+  &_huff_book_line_512x17_class3,
+
+  &_huff_book_line_512x17_0sub0,
+  &_huff_book_line_512x17_1sub0,
+  &_huff_book_line_512x17_1sub1,
+  &_huff_book_line_512x17_2sub1,
+  &_huff_book_line_512x17_2sub2,
+  &_huff_book_line_512x17_2sub3,
+  &_huff_book_line_512x17_3sub1,
+  &_huff_book_line_512x17_3sub2,
+  &_huff_book_line_512x17_3sub3,
+};
+
+static const static_codebook*const _floor_Xx0_books[]={
+  0
+};
+
+static const static_codebook*const *const _floor_books[11]={
+  _floor_128x4_books,
+  _floor_256x4_books,
+  _floor_128x7_books,
+  _floor_256x7_books,
+  _floor_128x11_books,
+  _floor_128x17_books,
+  _floor_256x4low_books,
+  _floor_1024x27_books,
+  _floor_2048x27_books,
+  _floor_512x17_books,
+  _floor_Xx0_books,
+};
+
+static const vorbis_info_floor1 _floor[11]={
+  /* 0: 128 x 4 */
+  {
+    1,{0},{4},{2},{0},
+    {{1,2,3,4}},
+    4,{0,128, 33,8,16,70},
+
+    60,30,500,   1.,18.,  128
+  },
+  /* 1: 256 x 4 */
+  {
+    1,{0},{4},{2},{0},
+    {{1,2,3,4}},
+    4,{0,256, 66,16,32,140},
+
+    60,30,500,   1.,18.,  256
+  },
+  /* 2: 128 x 7 */
+  {
+    2,{0,1},{3,4},{2,2},{0,1},
+    {{-1,2,3,4},{-1,5,6,7}},
+    4,{0,128, 14,4,58, 2,8,28,90},
+
+    60,30,500,   1.,18.,  128
+  },
+  /* 3: 256 x 7 */
+  {
+    2,{0,1},{3,4},{2,2},{0,1},
+    {{-1,2,3,4},{-1,5,6,7}},
+    4,{0,256, 28,8,116, 4,16,56,180},
+
+    60,30,500,   1.,18.,  256
+  },
+  /* 4: 128 x 11 */
+  {
+    4,{0,1,2,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2},
+    {{3},{4,5},{-1,6,7,8},{-1,9,10,11}},
+
+    2,{0,128,  8,33,  4,16,70,  2,6,12,  23,46,90},
+
+     60,30,500,   1,18.,  128
+  },
+  /* 5: 128 x 17 */
+  {
+    6,{0,1,1,2,3,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2},
+    {{3},{4,5},{-1,6,7,8},{-1,9,10,11}},
+    2,{0,128,  12,46,  4,8,16,  23,33,70,  2,6,10,  14,19,28,  39,58,90},
+
+    60,30,500,    1,18.,  128
+  },
+  /* 6: 256 x 4 (low bitrate version) */
+  {
+    1,{0},{4},{2},{0},
+    {{1,2,3,4}},
+    4,{0,256, 66,16,32,140},
+
+    60,30,500,   1.,18.,  256
+  },
+  /* 7: 1024 x 27 */
+  {
+    8,{0,1,2,2,3,3,4,4},{3,4,3,4,3},{0,1,1,2,2},{-1,0,1,2,3},
+    {{4},{5,6},{7,8},{-1,9,10,11},{-1,12,13,14}},
+    2,{0,1024,   93,23,372, 6,46,186,750,  14,33,65, 130,260,556,
+       3,10,18,28,  39,55,79,111,  158,220,312,  464,650,850},
+
+    60,30,500,    3,18.,  1024
+  },
+  /* 8: 2048 x 27 */
+  {
+    8,{0,1,2,2,3,3,4,4},{3,4,3,4,3},{0,1,1,2,2},{-1,0,1,2,3},
+    {{4},{5,6},{7,8},{-1,9,10,11},{-1,12,13,14}},
+    2,{0,2048,   186,46,744, 12,92,372,1500,  28,66,130, 260,520,1112,
+       6,20,36,56,  78,110,158,222,  316,440,624,  928,1300,1700},
+
+    60,30,500,    3,18.,  2048
+  },
+  /* 9: 512 x 17 */
+  {
+    6,{0,1,1,2,3,3},{2,3,3,3},{0,1,2,2},{-1,0,1,2},
+    {{3},{4,5},{-1,6,7,8},{-1,9,10,11}},
+    2,{0,512,  46,186,  16,33,65,  93,130,278,
+       7,23,39,  55,79,110,  156,232,360},
+
+    60,30,500,    1,18.,  512
+  },
+
+  /* 10: X x 0 (LFE floor; edge posts only) */
+  {
+    0,{0}, {0},{0},{-1},
+    {{-1}},
+    2,{0,12},
+    60,30,500,   1.,18.,  10
+  },
+
+};

+ 51 - 0
liboggvorbis/src/modes/psych_11.h

@@ -0,0 +1,51 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: 11kHz settings
+ last mod: $Id: psych_11.h 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+static const double _psy_lowpass_11[3]={4.5,5.5,30.,};
+
+static const att3 _psy_tone_masteratt_11[3]={
+  {{ 30,  25,  12},  0,   0},  /* 0 */
+  {{ 30,  25,  12},  0,   0},  /* 0 */
+  {{ 20,   0, -14},  0,   0}, /* 0 */
+};
+
+static const vp_adjblock _vp_tonemask_adj_11[3]={
+  /* adjust for mode zero */
+  /* 63     125     250     500     1     2     4     8    16 */
+  {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0,10, 2, 0,99,99,99}}, /* 0 */
+  {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0, 5, 0, 0,99,99,99}}, /* 1 */
+  {{-20,-20,-20,-20,-20,-16,-10, 0, 0, 0, 0, 0, 0, 0,99,99,99}}, /* 2 */
+};
+
+
+static const noise3 _psy_noisebias_11[3]={
+  /*  63     125     250     500      1k       2k      4k      8k     16k*/
+  {{{-10,-10,-10,-10, -5, -5, -5,  0,  4, 10, 10, 12, 12, 12, 99, 99, 99},
+    {-15,-15,-15,-15,-10,-10, -5,  0,  0,  4,  4,  5,  5, 10, 99, 99, 99},
+    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}},
+
+  {{{-10,-10,-10,-10, -5, -5, -5,  0,  4, 10, 10, 12, 12, 12, 99, 99, 99},
+    {-15,-15,-15,-15,-10,-10, -5, -5, -5,  0,  0,  0,  0,  0, 99, 99, 99},
+    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}},
+
+  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  4,  4,  5,  5, 99, 99, 99},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10, 99, 99, 99},
+    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24, 99, 99, 99}}},
+};
+
+static const double _noise_thresh_11[3]={ .3,.5,.5 };
+

+ 133 - 0
liboggvorbis/src/modes/psych_16.h

@@ -0,0 +1,133 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: 16kHz settings
+ last mod: $Id: psych_16.h 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+/* stereo mode by base quality level */
+static const adj_stereo _psy_stereo_modes_16[4]={
+  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  */
+  {{  4,  4,  4,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3},
+   {  6,  5,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
+   {  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  4,  4},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+  {{  4,  4,  4,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3},
+   {  6,  5,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
+   {  2,  2,  2,  2,  2,  2,  2,  2,  2,  3,  4,  4,  4,  4,  4},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+  {{  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3},
+   {  5,  4,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3},
+   {  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+  {{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
+   {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
+   {  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+};
+
+static const double _psy_lowpass_16[4]={6.5,8,30.,99.};
+
+static const att3 _psy_tone_masteratt_16[4]={
+  {{ 30,  25,  12},  0,   0},  /* 0 */
+  {{ 25,  22,  12},  0,   0},  /* 0 */
+  {{ 20,  12,   0},  0,   0},  /* 0 */
+  {{ 15,   0, -14},  0,   0}, /* 0 */
+};
+
+static const vp_adjblock _vp_tonemask_adj_16[4]={
+  /* adjust for mode zero */
+  /* 63     125     250     500       1     2     4     8    16 */
+  {{-20,-20,-20,-20,-20,-16,-10,  0,  0, 0, 0,10, 0, 0, 0, 0, 0}}, /* 0 */
+  {{-20,-20,-20,-20,-20,-16,-10,  0,  0, 0, 0,10, 0, 0, 0, 0, 0}}, /* 1 */
+  {{-20,-20,-20,-20,-20,-16,-10,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 2 */
+  {{-30,-30,-30,-30,-30,-26,-20,-10, -5, 0, 0, 0, 0, 0, 0, 0, 0}}, /* 2 */
+};
+
+
+static const noise3 _psy_noisebias_16_short[4]={
+  /*  63     125     250     500      1k       2k      4k      8k     16k*/
+  {{{-15,-15,-15,-15,-15,-10,-10,-5,   4, 10, 10, 10, 10, 12, 12, 14, 20},
+    {-15,-15,-15,-15,-15,-10,-10, -5,  0,  0,  4,  5,  5,  6,  8,  8, 15},
+    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}},
+
+  {{{-15,-15,-15,-15,-15,-10,-10,-5,   4,  6,  6,  6,  6,  8, 10, 12, 20},
+    {-15,-15,-15,-15,-15,-15,-15,-10, -5, -5, -5,  4,  5,  6,  8,  8, 15},
+    {-30,-30,-30,-30,-30,-24,-20,-14,-10,-10,-10,-10,-10,-10,-10,-10,-10}}},
+
+  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  4,  4,  5,  5,  5,  8, 12},
+    {-20,-20,-20,-20,-16,-12,-20,-14,-10,-10, -8,  0,  0,  0,  0,  2,  5},
+    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
+
+  {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5,  0,  0,  0,  6},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10,-10,-10, -6},
+    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
+};
+
+static const noise3 _psy_noisebias_16_impulse[4]={
+  /*  63     125     250     500      1k       2k      4k      8k     16k*/
+  {{{-15,-15,-15,-15,-15,-10,-10,-5,   4, 10, 10, 10, 10, 12, 12, 14, 20},
+    {-15,-15,-15,-15,-15,-10,-10, -5,  0,  0,  4,  5,  5,  6,  8,  8, 15},
+    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}},
+
+  {{{-15,-15,-15,-15,-15,-10,-10,-5,   4,  4,  4,  4,  5,  5,  6,  8, 15},
+    {-15,-15,-15,-15,-15,-15,-15,-10, -5, -5, -5,  0,  0,  0,  0,  4, 10},
+    {-30,-30,-30,-30,-30,-24,-20,-14,-10,-10,-10,-10,-10,-10,-10,-10,-10}}},
+
+  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  4, 10},
+    {-20,-20,-20,-20,-16,-12,-20,-14,-10,-10,-10,-10,-10,-10,-10, -7, -5},
+    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
+
+  {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5,  0,  0,  0,  6},
+    {-30,-30,-30,-30,-26,-22,-20,-18,-18,-18,-20,-20,-20,-20,-20,-20,-16},
+    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
+};
+
+static const noise3 _psy_noisebias_16[4]={
+  /*  63     125     250     500      1k       2k      4k      8k     16k*/
+  {{{-10,-10,-10,-10, -5, -5, -5,  0,  4,  6,  8,  8, 10, 10, 10, 14, 20},
+    {-10,-10,-10,-10,-10, -5, -2, -2,  0,  0,  0,  4,  5,  6,  8,  8, 15},
+    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}},
+
+  {{{-10,-10,-10,-10, -5, -5, -5,  0,  4,  6,  6,  6,  6,  8, 10, 12, 20},
+    {-15,-15,-15,-15,-15,-10, -5, -5,  0,  0,  0,  4,  5,  6,  8,  8, 15},
+    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -6, -6}}},
+
+  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  4,  4,  5,  5,  5,  8, 12},
+    {-20,-20,-20,-20,-16,-12,-20,-10, -5, -5,  0,  0,  0,  0,  0,  2,  5},
+    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
+
+  {{{-15,-15,-15,-15,-15,-12,-10, -8, -5, -5, -5, -5, -5,  0,  0,  0,  6},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10,-10,-10, -6},
+    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24,-20,-20,-20}}},
+};
+
+static const noiseguard _psy_noiseguards_16[4]={
+  {10,10,-1},
+  {10,10,-1},
+  {20,20,-1},
+  {20,20,-1},
+};
+
+static const double _noise_thresh_16[4]={ .3,.5,.5,.5 };
+
+static const int _noise_start_16[3]={ 256,256,9999 };
+static const int _noise_part_16[4]={ 8,8,8,8 };
+
+static const int _psy_ath_floater_16[4]={
+  -100,-100,-100,-105,
+};
+
+static const int _psy_ath_abs_16[4]={
+  -130,-130,-130,-140,
+};

+ 642 - 0
liboggvorbis/src/modes/psych_44.h

@@ -0,0 +1,642 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: key psychoacoustic settings for 44.1/48kHz
+ last mod: $Id: psych_44.h 16962 2010-03-11 07:30:34Z xiphmont $
+
+ ********************************************************************/
+
+
+/* preecho trigger settings *****************************************/
+
+static const vorbis_info_psy_global _psy_global_44[5]={
+
+  {8,   /* lines per eighth octave */
+   {20.f,14.f,12.f,12.f,12.f,12.f,12.f},
+   {-60.f,-30.f,-40.f,-40.f,-40.f,-40.f,-40.f}, 2,-75.f,
+   -6.f,
+   {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
+  },
+  {8,   /* lines per eighth octave */
+   {14.f,10.f,10.f,10.f,10.f,10.f,10.f},
+   {-40.f,-30.f,-25.f,-25.f,-25.f,-25.f,-25.f}, 2,-80.f,
+   -6.f,
+   {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
+  },
+  {8,   /* lines per eighth octave */
+   {12.f,10.f,10.f,10.f,10.f,10.f,10.f},
+   {-20.f,-20.f,-15.f,-15.f,-15.f,-15.f,-15.f}, 0,-80.f,
+   -6.f,
+   {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
+  },
+  {8,   /* lines per eighth octave */
+   {10.f,8.f,8.f,8.f,8.f,8.f,8.f},
+   {-20.f,-15.f,-12.f,-12.f,-12.f,-12.f,-12.f}, 0,-80.f,
+   -6.f,
+   {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
+  },
+  {8,   /* lines per eighth octave */
+   {10.f,6.f,6.f,6.f,6.f,6.f,6.f},
+   {-15.f,-15.f,-12.f,-12.f,-12.f,-12.f,-12.f}, 0,-85.f,
+   -6.f,
+   {99.},{{99.},{99.}},{0},{0},{{0.},{0.}}
+  },
+};
+
+/* noise compander lookups * low, mid, high quality ****************/
+static const compandblock _psy_compand_44[6]={
+  /* sub-mode Z short */
+  {{
+    0, 1, 2, 3, 4, 5, 6,  7,     /* 7dB */
+    8, 9,10,11,12,13,14, 15,     /* 15dB */
+    16,17,18,19,20,21,22, 23,     /* 23dB */
+    24,25,26,27,28,29,30, 31,     /* 31dB */
+    32,33,34,35,36,37,38, 39,     /* 39dB */
+  }},
+  /* mode_Z nominal short */
+  {{
+     0, 1, 2, 3, 4, 5, 6,  6,     /* 7dB */
+     7, 7, 7, 7, 6, 6, 6,  7,     /* 15dB */
+     7, 8, 9,10,11,12,13, 14,     /* 23dB */
+    15,16,17,17,17,18,18, 19,     /* 31dB */
+    19,19,20,21,22,23,24, 25,     /* 39dB */
+  }},
+  /* mode A short */
+  {{
+    0, 1, 2, 3, 4, 5, 5,  5,     /* 7dB */
+    6, 6, 6, 5, 4, 4, 4,  4,     /* 15dB */
+    4, 4, 5, 5, 5, 6, 6,  6,     /* 23dB */
+    7, 7, 7, 8, 8, 8, 9, 10,     /* 31dB */
+    11,12,13,14,15,16,17, 18,     /* 39dB */
+  }},
+  /* sub-mode Z long */
+  {{
+     0, 1, 2, 3, 4, 5, 6,  7,     /* 7dB */
+     8, 9,10,11,12,13,14, 15,     /* 15dB */
+    16,17,18,19,20,21,22, 23,     /* 23dB */
+    24,25,26,27,28,29,30, 31,     /* 31dB */
+    32,33,34,35,36,37,38, 39,     /* 39dB */
+  }},
+  /* mode_Z nominal long */
+  {{
+    0, 1, 2, 3, 4, 5, 6,  7,     /* 7dB */
+    8, 9,10,11,12,12,13, 13,     /* 15dB */
+    13,14,14,14,15,15,15, 15,     /* 23dB */
+    16,16,17,17,17,18,18, 19,     /* 31dB */
+    19,19,20,21,22,23,24, 25,     /* 39dB */
+  }},
+  /* mode A long */
+  {{
+    0, 1, 2, 3, 4, 5, 6,  7,     /* 7dB */
+    8, 8, 7, 6, 5, 4, 4,  4,     /* 15dB */
+    4, 4, 5, 5, 5, 6, 6,  6,     /* 23dB */
+    7, 7, 7, 8, 8, 8, 9, 10,     /* 31dB */
+    11,12,13,14,15,16,17, 18,     /* 39dB */
+  }}
+};
+
+/* tonal masking curve level adjustments *************************/
+
+static const vp_adjblock _vp_tonemask_adj_longblock[12]={
+
+   /* 63     125     250     500       1       2       4       8      16 */
+
+   {{ -3, -8,-13,-15,-10,-10,-10,-10,-10,-10,-10,  0,  0,  0,  0,  0,  0}}, /* -1 */
+
+/* {{-15,-15,-15,-15,-10, -8, -4, -2,  0,  0,  0, 10,  0,  0,  0,  0,  0}},    0 */
+   {{ -4,-10,-14,-16,-15,-14,-13,-12,-12,-12,-11, -1, -1, -1, -1, -1,  0}}, /* 0 */
+
+/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  5,  0,  0,  0,  0,  0}},    1 */
+   {{ -6,-12,-14,-16,-15,-15,-14,-13,-13,-12,-12, -2, -2, -1, -1, -1,  0}}, /* 1 */
+
+/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    2 */
+   {{-12,-13,-14,-16,-16,-16,-15,-14,-13,-12,-12, -6, -3, -1, -1, -1,  0}}, /* 2 */
+
+/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    3 */
+   {{-15,-15,-15,-16,-16,-16,-16,-14,-13,-13,-13,-10, -4, -2, -1, -1,  0}}, /* 3 */
+
+/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}}, *//* 4 */
+   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7  -3, -1, -1 , 0}}, /* 4 */
+
+/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    5 */
+   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7  -3, -1, -1 , 0}}, /* 5 */
+
+/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    6 */
+   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -8, -4, -2, -2,  0}}, /* 6 */
+
+/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    7 */
+   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 7 */
+
+/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    8 */
+   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 8 */
+
+/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    9 */
+   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 9 */
+
+/* {{-15,-15,-15,-15,-15,-12,-10, -8,  0,  0,  0,  0,  0,  0,  0,  0,  0}},    10 */
+   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 10 */
+};
+
+static const vp_adjblock _vp_tonemask_adj_otherblock[12]={
+   /* 63     125     250     500       1       2       4       8      16 */
+
+   {{ -3, -8,-13,-15,-10,-10, -9, -9, -9, -9, -9,  1,  1,  1,  1,  1,  1}}, /* -1 */
+
+/* {{-20,-20,-20,-20,-14,-12,-10, -8, -4,  0,  0, 10,  0,  0,  0,  0,  0}},    0 */
+   {{ -4,-10,-14,-16,-14,-13,-12,-12,-11,-11,-10,  0,  0,  0,  0,  0,  0}}, /* 0 */
+
+/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  5,  0,  0,  0,  0,  0}},    1 */
+   {{ -6,-12,-14,-16,-15,-15,-14,-13,-13,-12,-12, -2, -2, -1,  0,  0,  0}}, /* 1 */
+
+/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    2 */
+   {{-12,-13,-14,-16,-16,-16,-15,-14,-13,-12,-12, -5, -2, -1,  0,  0,  0}}, /* 2 */
+
+/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    3 */
+   {{-15,-15,-15,-16,-16,-16,-16,-14,-13,-13,-13,-10, -4, -2,  0,  0,  0}}, /* 3 */
+
+/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    4 */
+   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7  -3, -1, -1 , 0}}, /* 4 */
+
+/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    5 */
+   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-13,-11, -7  -3, -1, -1 , 0}}, /* 5 */
+
+/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    6 */
+   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -8, -4, -2, -2,  0}}, /* 6 */
+
+/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    7 */
+   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 7 */
+
+/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    8 */
+   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 8 */
+
+/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    9 */
+   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 9 */
+
+/* {{-20,-20,-20,-20,-20,-18,-16,-14,-10,  0,  0,  0,  0,  0,  0,  0,  0}},    10 */
+   {{-16,-16,-16,-16,-16,-16,-16,-15,-14,-14,-14,-12, -9, -4, -2, -2,  0}}, /* 10 */
+};
+
+/* noise bias (transition block) */
+static const noise3 _psy_noisebias_trans[12]={
+  /*  63     125     250     500      1k       2k      4k      8k     16k*/
+  /* -1 */
+  {{{-10,-10,-10,-10,-10, -4,  0,  0,  4,  8,  8,  8,  8, 10, 12, 14, 20},
+    {-30,-30,-30,-30,-26,-20,-16, -8, -6, -6, -2,  2,  2,  3,  6,  6, 15},
+    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},
+  /* 0
+  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  4,  4,  5,  5,  5,  8,  10},
+    {-30,-30,-30,-30,-26,-22,-20,-14, -8, -4,  0,  0,  0,  0,  2,  4,  10},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -4, -4, -4,  -2}}},*/
+  {{{-15,-15,-15,-15,-15,-12, -6, -4,  0,  2,  4,  4,  5,  5,  5,  8,  10},
+    {-30,-30,-30,-30,-26,-22,-20,-14, -8, -4,  0,  0,  0,  0,  2,  3,   6},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -4, -4, -4,  -2}}},
+  /* 1
+  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  4,  4,  5,  5,  5,  8,  10},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, -2, -2, -2,  0,  2,  8},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}},*/
+  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  4,  4,  5,  5,  5,  8,  10},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, -2, -2, -2,  0,  1,   4},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6,  -4}}},
+  /* 2
+  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  2,  2,  4,  4,  5,  6,  10},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2, -2, -2, -2,  0,  2,  6},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}}, */
+  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  2,  2,  4,  4,  5,  6,  10},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -2, -1,  0,  3},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -7, -4}}},
+  /* 3
+  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  2,  2,  4,  4,  4,  5,  8},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -1,  1,  6},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
+  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  2,  2,  4,  4,  4,  5,  8},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -2,  0,  2},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},
+  /* 4
+  {{{-20,-20,-20,-20,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -1,  1,  5},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
+  {{{-20,-20,-20,-20,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -3, -3, -3, -3, -2, -1,  1},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},
+  /* 5
+  {{{-24,-24,-24,-24,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
+    {-32,-32,-32,-32,-28,-24,-22,-16,-12, -6, -4, -4, -4, -4, -2, -1,  2},
+    {-34,-34,-34,-34,-30,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -5}}}, */
+  {{{-24,-24,-24,-24,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
+    {-32,-32,-32,-32,-28,-24,-22,-16,-12, -6, -4, -4, -4, -4, -3, -1,  0},
+    {-34,-34,-34,-34,-30,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -5}}},
+  /* 6
+  {{{-24,-24,-24,-24,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
+    {-32,-32,-32,-32,-28,-24,-24,-18,-14, -8, -6, -6, -6, -6, -4, -2,  1},
+    {-34,-34,-34,-34,-30,-26,-24,-18,-17,-15,-15,-15,-15,-13,-13,-12, -8}}},*/
+  {{{-24,-24,-24,-24,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
+    {-32,-32,-32,-32,-28,-24,-24,-18,-14, -8, -6, -6, -6, -6, -5, -2,  0},
+    {-34,-34,-34,-34,-30,-26,-26,-24,-22,-19,-19,-19,-19,-18,-17,-16,-12}}},
+  /* 7
+  {{{-24,-24,-24,-24,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
+    {-32,-32,-32,-32,-28,-24,-24,-18,-14,-12,-10, -8, -8, -8, -6, -4,  0},
+    {-34,-34,-34,-34,-30,-26,-26,-24,-22,-19,-19,-19,-19,-18,-17,-16,-12}}},*/
+  {{{-24,-24,-24,-24,-20,-18,-14, -8, -1,  1,  1,  1,  2,  3,  3,  4,  7},
+    {-32,-32,-32,-32,-28,-24,-24,-24,-18,-14,-12,-10,-10,-10, -8, -6, -2},
+    {-34,-34,-34,-34,-30,-26,-26,-26,-24,-24,-24,-24,-24,-24,-24,-20,-16}}},
+  /* 8
+  {{{-24,-24,-24,-24,-22,-20,-15,-10, -8, -2,  0,  0,  0,  1,  2,  3,  7},
+    {-36,-36,-36,-36,-30,-30,-30,-24,-18,-14,-12,-10,-10,-10, -8, -6, -2},
+    {-36,-36,-36,-36,-34,-30,-28,-26,-24,-24,-24,-24,-24,-24,-24,-20,-16}}},*/
+  {{{-24,-24,-24,-24,-22,-20,-15,-10, -8, -2,  0,  0,  0,  1,  2,  3,  7},
+    {-36,-36,-36,-36,-30,-30,-30,-24,-20,-16,-16,-16,-16,-14,-12,-10, -7},
+    {-36,-36,-36,-36,-34,-30,-28,-26,-24,-30,-30,-30,-30,-30,-30,-24,-20}}},
+  /* 9
+  {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2,  2},
+    {-36,-36,-36,-36,-34,-32,-32,-28,-20,-16,-16,-16,-16,-14,-12,-10, -7},
+    {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-24,-20}}},*/
+  {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2,  2},
+    {-38,-38,-38,-38,-36,-34,-34,-30,-24,-20,-20,-20,-20,-18,-16,-12,-10},
+    {-40,-40,-40,-40,-40,-40,-40,-38,-35,-35,-35,-35,-35,-35,-35,-35,-30}}},
+  /* 10 */
+  {{{-30,-30,-30,-30,-30,-30,-30,-28,-20,-14,-14,-14,-14,-14,-14,-12,-10},
+    {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-30,-30,-30,-30,-30,-30,-20},
+    {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}},
+};
+
+/*  noise bias (long block) */
+static const noise3 _psy_noisebias_long[12]={
+  /*63     125     250     500      1k       2k      4k      8k     16k*/
+  /* -1 */
+  {{{-10,-10,-10,-10,-10, -4,  0,  0,  0,  6,  6,  6,  6, 10, 10, 12,  20},
+    {-20,-20,-20,-20,-20,-20,-10, -2,  0,  0,  0,  0,  0,  2,  4,  6,  15},
+    {-20,-20,-20,-20,-20,-20,-20,-10, -6, -6, -6, -6, -6, -4, -4, -4, -2}}},
+
+  /* 0 */
+  /*  {{{-10,-10,-10,-10,-10,-10, -8,  2,  2,  2,  4,  4,  5,  5,  5,  8,  10},
+      {-20,-20,-20,-20,-20,-20,-20,-14, -6,  0,  0,  0,  0,  0,  2,  4,  10},
+      {-20,-20,-20,-20,-20,-20,-20,-14, -8, -6, -6, -6, -6, -4, -4, -4, -2}}},*/
+  {{{-10,-10,-10,-10,-10,-10, -8,  2,  2,  2,  4,  4,  5,  5,  5,  8,  10},
+    {-20,-20,-20,-20,-20,-20,-20,-14, -6,  0,  0,  0,  0,  0,  2,  3,  6},
+    {-20,-20,-20,-20,-20,-20,-20,-14, -8, -6, -6, -6, -6, -4, -4, -4, -2}}},
+  /* 1 */
+  /*  {{{-10,-10,-10,-10,-10,-10, -8, -4,  0,  2,  4,  4,  5,  5,  5,  8,  10},
+      {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -2, -2, -2, -2,  0,  2,  8},
+      {-20,-20,-20,-20,-20,-20,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}},*/
+  {{{-10,-10,-10,-10,-10,-10, -8, -4,  0,  2,  4,  4,  5,  5,  5,  8,  10},
+    {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -2, -2, -2, -2,  0,  1,  4},
+    {-20,-20,-20,-20,-20,-20,-20,-14,-10, -8, -8, -8, -8, -6, -6, -6, -4}}},
+  /* 2 */
+  /*  {{{-10,-10,-10,-10,-10,-10,-10, -8,  0,  2,  2,  2,  4,  4,  5,  6,  10},
+      {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -2, -2, -2, -2,  0,  2,  6},
+      {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
+  {{{-10,-10,-10,-10,-10,-10,-10, -8,  0,  2,  2,  2,  4,  4,  5,  6,  10},
+    {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -2, -1,  0,  3},
+    {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},
+  /* 3 */
+  /*  {{{-10,-10,-10,-10,-10,-10,-10, -8,  0,  2,  2,  2,  4,  4,  4,  5,  8},
+      {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -1,  1,  6},
+      {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
+  {{{-10,-10,-10,-10,-10,-10,-10, -8,  0,  2,  2,  2,  4,  4,  4,  5,  8},
+    {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -2,  0,  2},
+    {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -5}}},
+  /* 4 */
+  /*  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  1,  1,  1,  2,  3,  3,  4,  7},
+      {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -1,  1,  5},
+      {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -4}}},*/
+  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  1,  1,  1,  2,  3,  3,  4,  7},
+    {-20,-20,-20,-20,-20,-20,-20,-14,-10, -4, -3, -3, -3, -3, -2, -1,  1},
+    {-20,-20,-20,-20,-20,-20,-20,-14,-10,-10,-10,-10,-10, -8, -8, -8, -7}}},
+  /* 5 */
+  /*  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  1,  1,  1,  2,  3,  3,  4,  7},
+      {-22,-22,-22,-22,-22,-22,-22,-16,-12, -6, -4, -4, -4, -4, -2, -1,  2},
+      {-24,-24,-24,-24,-24,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -5}}},*/
+  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  1,  1,  1,  2,  3,  3,  4,  7},
+    {-22,-22,-22,-22,-22,-22,-22,-16,-12, -6, -4, -4, -4, -4, -3, -1,  0},
+    {-24,-24,-24,-24,-24,-24,-24,-18,-14,-12,-12,-12,-12,-10,-10, -9, -8}}},
+  /* 6 */
+  /*  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  1,  1,  1,  2,  3,  3,  4,  7},
+      {-24,-24,-24,-24,-24,-24,-24,-18,-14, -8, -6, -6, -6, -6, -4, -2,  1},
+      {-26,-26,-26,-26,-26,-26,-26,-18,-16,-15,-15,-15,-15,-13,-13,-12, -8}}},*/
+  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  1,  1,  1,  2,  3,  3,  4,  7},
+    {-24,-24,-24,-24,-24,-24,-24,-18,-14, -8, -6, -6, -6, -6, -5, -2,  0},
+    {-26,-26,-26,-26,-26,-26,-26,-18,-16,-15,-15,-15,-15,-13,-13,-12,-10}}},
+  /* 7 */
+  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  1,  1,  1,  2,  3,  3,  4,  7},
+    {-24,-24,-24,-24,-24,-24,-24,-18,-14,-10, -8, -8, -8, -8, -6, -4,  0},
+    {-26,-26,-26,-26,-26,-26,-26,-22,-20,-19,-19,-19,-19,-18,-17,-16,-12}}},
+  /* 8 */
+  {{{-15,-15,-15,-15,-15,-15,-15,-10, -4,  0,  0,  0,  0,  1,  2,  3,  7},
+    {-26,-26,-26,-26,-26,-26,-26,-20,-16,-12,-10,-10,-10,-10, -8, -6, -2},
+    {-28,-28,-28,-28,-28,-28,-28,-26,-24,-24,-24,-24,-24,-24,-24,-20,-16}}},
+  /* 9 */
+  {{{-22,-22,-22,-22,-22,-22,-22,-18,-14, -8, -4, -4, -4, -4, -4, -2,  2},
+    {-26,-26,-26,-26,-26,-26,-26,-22,-18,-16,-16,-16,-16,-14,-12,-10, -7},
+    {-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-24,-20}}},
+  /* 10 */
+  {{{-24,-24,-24,-24,-24,-24,-24,-24,-24,-18,-14,-14,-14,-14,-14,-12,-10},
+    {-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-20},
+    {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}},
+};
+
+/* noise bias (impulse block) */
+static const noise3 _psy_noisebias_impulse[12]={
+  /*  63     125     250     500      1k      2k      4k      8k     16k*/
+  /* -1 */
+  {{{-10,-10,-10,-10,-10, -4,  0,  0,  4,  8,  8,  8,  8, 10, 12, 14, 20},
+    {-30,-30,-30,-30,-26,-20,-16, -8, -6, -6, -2,  2,  2,  3,  6,  6, 15},
+    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},
+
+  /* 0 */
+  /*  {{{-10,-10,-10,-10,-10, -4,  0,  0,  4,  4,  8,  8,  8, 10, 12, 14, 20},
+      {-30,-30,-30,-30,-26,-22,-20,-14, -6, -2,  0,  0,  0,  0,  2,  4,  10},
+      {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},*/
+  {{{-10,-10,-10,-10,-10, -4,  0,  0,  4,  4,  8,  8,  8, 10, 12, 14, 20},
+    {-30,-30,-30,-30,-26,-22,-20,-14, -6, -2,  0,  0,  0,  0,  2,  3,  6},
+    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},
+  /* 1 */
+  {{{-12,-12,-12,-12,-12, -8, -6, -4,  0,  4,  4,  4,  4, 10, 12, 14, 20},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -4, -4, -2, -2, -2, -2,  2},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8,-10,-10, -8, -8, -8, -6, -4}}},
+  /* 2 */
+  {{{-14,-14,-14,-14,-14,-10, -8, -6, -2,  2,  2,  2,  2,  8, 10, 10, 16},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2,  0},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}},
+  /* 3 */
+  {{{-14,-14,-14,-14,-14,-10, -8, -6, -2,  2,  2,  2,  2,  6,  8,  8, 14},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2,  0},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}},
+  /* 4 */
+  {{{-16,-16,-16,-16,-16,-12,-10, -6, -2,  0,  0,  0,  0,  4,  6,  6, 12},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -4, -4, -4, -2,  0},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10,-10,-10,-10,-10,-10,-10, -8, -4}}},
+  /* 5 */
+  {{{-20,-20,-20,-20,-20,-18,-14,-10, -4,  0,  0,  0,  0,  4,  4,  6, 11},
+    {-32,-32,-32,-32,-28,-24,-22,-16,-10, -6, -8, -8, -6, -6, -6, -4, -2},
+    {-34,-34,-34,-34,-30,-26,-24,-18,-14,-12,-12,-12,-12,-12,-10, -9, -5}}},
+  /* 6
+  {{{-20,-20,-20,-20,-20,-18,-14,-10, -4,  0,  0,  0,  0,  4,  4,  6, 11},
+      {-34,-34,-34,-34,-30,-30,-24,-20,-12,-12,-14,-14,-10, -9, -8, -6, -4},
+      {-34,-34,-34,-34,-34,-30,-26,-20,-16,-15,-15,-15,-15,-15,-13,-12, -8}}},*/
+  {{{-20,-20,-20,-20,-20,-18,-14,-10, -4,  0,  0,  0,  0,  4,  4,  6, 11},
+    {-34,-34,-34,-34,-30,-30,-30,-24,-16,-16,-16,-16,-16,-16,-14,-14,-12},
+    {-36,-36,-36,-36,-36,-34,-28,-24,-20,-20,-20,-20,-20,-20,-20,-18,-16}}},
+  /* 7 */
+  /*  {{{-22,-22,-22,-22,-22,-20,-14,-10, -6,  0,  0,  0,  0,  4,  4,  6, 11},
+      {-34,-34,-34,-34,-30,-30,-24,-20,-14,-14,-16,-16,-14,-12,-10,-10,-10},
+      {-34,-34,-34,-34,-32,-32,-30,-24,-20,-19,-19,-19,-19,-19,-17,-16,-12}}},*/
+  {{{-22,-22,-22,-22,-22,-20,-14,-10, -6,  0,  0,  0,  0,  4,  4,  6, 11},
+    {-34,-34,-34,-34,-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-24,-22},
+    {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-30,-24}}},
+  /* 8 */
+  /*  {{{-24,-24,-24,-24,-24,-22,-14,-10, -6, -1, -1, -1, -1,  3,  3,  5, 10},
+      {-34,-34,-34,-34,-30,-30,-30,-24,-20,-20,-20,-20,-20,-18,-16,-16,-14},
+      {-36,-36,-36,-36,-36,-34,-28,-24,-24,-24,-24,-24,-24,-24,-24,-20,-16}}},*/
+  {{{-24,-24,-24,-24,-24,-22,-14,-10, -6, -1, -1, -1, -1,  3,  3,  5, 10},
+    {-34,-34,-34,-34,-34,-32,-32,-30,-26,-26,-26,-26,-26,-26,-26,-26,-24},
+    {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-30,-24}}},
+  /* 9 */
+  /*  {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2,  2},
+      {-36,-36,-36,-36,-34,-32,-32,-30,-26,-26,-26,-26,-26,-22,-20,-20,-18},
+      {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-24,-20}}},*/
+  {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -4, -4, -4, -4, -4, -2,  2},
+    {-36,-36,-36,-36,-34,-32,-32,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26},
+    {-40,-40,-40,-40,-40,-40,-40,-32,-30,-30,-30,-30,-30,-30,-30,-24,-20}}},
+  /* 10 */
+  {{{-30,-30,-30,-30,-30,-26,-24,-24,-24,-20,-16,-16,-16,-16,-16,-14,-12},
+    {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-30,-30,-30,-30,-30,-30,-26},
+    {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}},
+};
+
+/* noise bias (padding block) */
+static const noise3 _psy_noisebias_padding[12]={
+  /*  63     125     250     500      1k       2k      4k      8k     16k*/
+
+  /* -1 */
+  {{{-10,-10,-10,-10,-10, -4,  0,  0,  4,  8,  8,  8,  8, 10, 12, 14, 20},
+    {-30,-30,-30,-30,-26,-20,-16, -8, -6, -6, -2,  2,  2,  3,  6,  6, 15},
+    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, -6, -4, -2}}},
+
+  /* 0 */
+  {{{-10,-10,-10,-10,-10, -4,  0,  0,  4,  8,  8,  8,  8, 10, 12, 14, 20},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -2,  2,  3,  6,  6,  8, 10},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4, -4, -4, -4, -4, -2,  0,  2}}},
+  /* 1 */
+  {{{-12,-12,-12,-12,-12, -8, -6, -4,  0,  4,  4,  4,  4, 10, 12, 14, 20},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4,  0,  0,  0,  2,  2,  4,  8},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -6, -6, -6, -6, -4, -2,  0}}},
+  /* 2 */
+  /*  {{{-14,-14,-14,-14,-14,-10, -8, -6, -2,  2,  2,  2,  2,  8, 10, 10, 16},
+      {-30,-30,-30,-30,-26,-22,-20,-14,-10, -4,  0,  0,  0,  2,  2,  4,  8},
+      {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}},*/
+  {{{-14,-14,-14,-14,-14,-10, -8, -6, -2,  2,  2,  2,  2,  8, 10, 10, 16},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -1, -1, -1,  0,  0,  2,  6},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}},
+  /* 3 */
+  {{{-14,-14,-14,-14,-14,-10, -8, -6, -2,  2,  2,  2,  2,  6,  8,  8, 14},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -1, -1, -1,  0,  0,  2,  6},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}},
+  /* 4 */
+  {{{-16,-16,-16,-16,-16,-12,-10, -6, -2,  0,  0,  0,  0,  4,  6,  6, 12},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -6, -1, -1, -1, -1,  0,  2,  6},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-10, -8, -8, -8, -8, -8, -6, -4, -2}}},
+  /* 5 */
+  {{{-20,-20,-20,-20,-20,-18,-14,-10, -4,  0,  0,  0,  0,  4,  6,  6, 12},
+    {-32,-32,-32,-32,-28,-24,-22,-16,-12, -6, -3, -3, -3, -3, -2,  0,  4},
+    {-34,-34,-34,-34,-30,-26,-24,-18,-14,-10,-10,-10,-10,-10, -8, -5, -3}}},
+  /* 6 */
+  {{{-20,-20,-20,-20,-20,-18,-14,-10, -4,  0,  0,  0,  0,  4,  6,  6, 12},
+    {-34,-34,-34,-34,-30,-30,-24,-20,-14, -8, -4, -4, -4, -4, -3, -1,  4},
+    {-34,-34,-34,-34,-34,-30,-26,-20,-16,-13,-13,-13,-13,-13,-11, -8, -6}}},
+  /* 7 */
+  {{{-20,-20,-20,-20,-20,-18,-14,-10, -4,  0,  0,  0,  0,  4,  6,  6, 12},
+    {-34,-34,-34,-34,-30,-30,-30,-24,-16,-10, -8, -6, -6, -6, -5, -3,  1},
+    {-34,-34,-34,-34,-32,-32,-28,-22,-18,-16,-16,-16,-16,-16,-14,-12,-10}}},
+  /* 8 */
+  {{{-22,-22,-22,-22,-22,-20,-14,-10, -4,  0,  0,  0,  0,  3,  5,  5, 11},
+    {-34,-34,-34,-34,-30,-30,-30,-24,-16,-12,-10, -8, -8, -8, -7, -5, -2},
+    {-36,-36,-36,-36,-36,-34,-28,-22,-20,-20,-20,-20,-20,-20,-20,-16,-14}}},
+  /* 9 */
+  {{{-28,-28,-28,-28,-28,-28,-28,-20,-14, -8, -2, -2, -2, -2,  0,  2,  6},
+    {-36,-36,-36,-36,-34,-32,-32,-24,-16,-12,-12,-12,-12,-12,-10, -8, -5},
+    {-40,-40,-40,-40,-40,-40,-40,-32,-26,-24,-24,-24,-24,-24,-24,-20,-18}}},
+  /* 10 */
+  {{{-30,-30,-30,-30,-30,-26,-24,-24,-24,-20,-12,-12,-12,-12,-12,-10, -8},
+    {-40,-40,-40,-40,-40,-40,-40,-40,-35,-30,-25,-25,-25,-25,-25,-25,-15},
+    {-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40,-40}}},
+};
+
+
+static const noiseguard _psy_noiseguards_44[4]={
+  {3,3,15},
+  {3,3,15},
+  {10,10,100},
+  {10,10,100},
+};
+
+static const int _psy_tone_suppress[12]={
+  -20,-20,-20,-20,-20,-24,-30,-40,-40,-45,-45,-45,
+};
+static const int _psy_tone_0dB[12]={
+  90,90,95,95,95,95,105,105,105,105,105,105,
+};
+static const int _psy_noise_suppress[12]={
+  -20,-20,-24,-24,-24,-24,-30,-40,-40,-45,-45,-45,
+};
+
+static const vorbis_info_psy _psy_info_template={
+  /* blockflag */
+  -1,
+  /* ath_adjatt, ath_maxatt */
+  -140.,-140.,
+  /* tonemask att boost/decay,suppr,curves */
+  {0.f,0.f,0.f},     0.,0.,    -40.f, {0.},
+
+  /*noisemaskp,supp, low/high window, low/hi guard, minimum */
+  1,          -0.f,           .5f, .5f,         0,0,0,
+  /* noiseoffset*3, noisecompand, max_curve_dB */
+  {{-1},{-1},{-1}},{-1},105.f,
+  /* noise normalization - noise_p, start, partition, thresh. */
+  0,-1,-1,0.,
+};
+
+/* ath ****************/
+
+static const int _psy_ath_floater[12]={
+  -100,-100,-100,-100,-100,-100,-105,-105,-105,-105,-110,-120,
+};
+static const int _psy_ath_abs[12]={
+  -130,-130,-130,-130,-140,-140,-140,-140,-140,-140,-140,-150,
+};
+
+/* stereo setup.  These don't map directly to quality level, there's
+   an additional indirection as several of the below may be used in a
+   single bitmanaged stream
+
+****************/
+
+/* various stereo possibilities */
+
+/* stereo mode by base quality level */
+static const adj_stereo _psy_stereo_modes_44[12]={
+  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         -1  */
+  {{  4,  4,  4,  4,  4,  4,  4,  3,  2,  2,  1,  0,  0,  0,  0},
+   {  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  5,  4,  3},
+   {  1,  2,  3,  4,  4,  4,  4,  4,  4,  5,  6,  7,  8,  8,  8},
+   { 12,12.5, 13,13.5, 14,14.5, 15, 99, 99, 99, 99, 99, 99, 99, 99}},
+
+/*    0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         0  */
+  {{  4,  4,  4,  4,  4,  4,  4,  3,  2,  1,  0,  0,  0,  0,  0},
+   {  8,  8,  8,  8,  6,  6,  5,  5,  5,  5,  5,  5,  5,  4,  3},
+   {  1,  2,  3,  4,  4,  5,  6,  6,  6,  6,  6,  8,  8,  8,  8},
+   { 12,12.5, 13,13.5, 14,14.5, 15, 99, 99, 99, 99, 99, 99, 99, 99}},
+
+
+  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         1  */
+  {{  3,  3,  3,  3,  3,  3,  3,  3,  2,  1,  0,  0,  0,  0,  0},
+   {  8,  8,  8,  8,  6,  6,  5,  5,  5,  5,  5,  5,  5,  4,  3},
+   {  1,  2,  3,  4,  4,  5,  6,  6,  6,  6,  6,  8,  8,  8,  8},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+
+
+  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         2  */
+  {{  3,  3,  3,  3,  3,  3,  3,  2,  1,  1,  0,  0,  0,  0,  0},
+   {  8,  8,  6,  6,  5,  5,  4,  4,  4,  4,  4,  4,  3,  2,  1},
+   {  3,  4,  4,  5,  5,  6,  6,  6,  6,  6,  6,  8,  8,  8,  8},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         3  */
+  {{  2,  2,  2,  2,  2,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0},
+   {  5,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  3,  2,  1},
+   {  4,  4,  5,  6,  6,  6,  6,  6,  8,  8, 10, 10, 10, 10, 10},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         4  */
+  {{  2,  2,  2,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0},
+   {  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  3,  3,  2,  1,  0},
+   {  6,  6,  6,  8,  8,  8,  8,  8,  8,  8, 10, 10, 10, 10, 10},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         5  */
+  {{  2,  2,  2,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
+   {  3,  3,  3,  3,  3,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0},
+   {  6,  7,  8,  8,  8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         6  */
+  {{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
+   {  3,  3,  3,  2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0},
+   {  8,  8,  8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         7  */
+  {{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
+   {  3,  3,  3,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
+   {  8,  8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         8  */
+  {{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
+   {  2,  2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
+   {  8, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14         9  */
+  {{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
+   {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
+   {  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14        10  */
+  {{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
+   {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
+   {  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+};
+
+/* tone master attenuation by base quality mode and bitrate tweak */
+static const att3 _psy_tone_masteratt_44[12]={
+  {{ 35,  21,   9},  0,    0}, /* -1 */
+  {{ 30,  20,   8}, -2, 1.25}, /* 0 */
+  /*  {{ 25,  14,   4},  0,    0}, *//* 1 */
+  {{ 25,  12,   2},  0,    0}, /* 1 */
+  /*  {{ 20,  10,  -2},  0,    0}, *//* 2 */
+  {{ 20,   9,  -3},  0,    0}, /* 2 */
+  {{ 20,   9,  -4},  0,    0}, /* 3 */
+  {{ 20,   9,  -4},  0,    0}, /* 4 */
+  {{ 20,   6,  -6},  0,    0}, /* 5 */
+  {{ 20,   3, -10},  0,    0}, /* 6 */
+  {{ 18,   1, -14},  0,    0}, /* 7 */
+  {{ 18,   0, -16},  0,    0}, /* 8 */
+  {{ 18,  -2, -16},  0,    0}, /* 9 */
+  {{ 12,  -2, -20},  0,    0}, /* 10 */
+};
+
+/* lowpass by mode **************/
+static const double _psy_lowpass_44[12]={
+  /*  15.1,15.8,16.5,17.9,20.5,48.,999.,999.,999.,999.,999. */
+  13.9,15.1,15.8,16.5,17.2,18.9,20.1,48.,999.,999.,999.,999.
+};
+
+/* noise normalization **********/
+
+static const int _noise_start_short_44[11]={
+  /*  16,16,16,16,32,32,9999,9999,9999,9999 */
+  32,16,16,16,32,9999,9999,9999,9999,9999,9999
+};
+static const int _noise_start_long_44[11]={
+  /*  128,128,128,256,512,512,9999,9999,9999,9999 */
+  256,128,128,256,512,9999,9999,9999,9999,9999,9999
+};
+
+static const int _noise_part_short_44[11]={
+    8,8,8,8,8,8,8,8,8,8,8
+};
+static const int _noise_part_long_44[11]={
+    32,32,32,32,32,32,32,32,32,32,32
+};
+
+static const double _noise_thresh_44[11]={
+  /*  .2,.2,.3,.4,.5,.5,9999.,9999.,9999.,9999., */
+   .2,.2,.2,.4,.6,9999.,9999.,9999.,9999.,9999.,9999.,
+};
+
+static const double _noise_thresh_5only[2]={
+ .5,.5,
+};

+ 101 - 0
liboggvorbis/src/modes/psych_8.h

@@ -0,0 +1,101 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: 8kHz psychoacoustic settings
+ last mod: $Id: psych_8.h 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+static const att3 _psy_tone_masteratt_8[3]={
+  {{ 32,  25,  12},  0,   0},  /* 0 */
+  {{ 30,  25,  12},  0,   0},  /* 0 */
+  {{ 20,   0, -14},  0,   0}, /* 0 */
+};
+
+static const vp_adjblock _vp_tonemask_adj_8[3]={
+  /* adjust for mode zero */
+  /* 63     125     250     500     1     2     4     8    16 */
+  {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0,10, 0, 0,99,99,99}}, /* 1 */
+  {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0,10, 0, 0,99,99,99}}, /* 1 */
+  {{-15,-15,-15,-15,-10,-10, -6, 0, 0, 0, 0, 0, 0, 0,99,99,99}}, /* 1 */
+};
+
+
+static const noise3 _psy_noisebias_8[3]={
+  /*  63     125     250     500      1k       2k      4k      8k     16k*/
+  {{{-10,-10,-10,-10, -5, -5, -5,  0,  4,  8,  8,  8, 10, 10, 99, 99, 99},
+    {-10,-10,-10,-10, -5, -5, -5,  0,  0,  4,  4,  4,  4,  4, 99, 99, 99},
+    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}},
+
+  {{{-10,-10,-10,-10, -5, -5, -5,  0,  4,  8,  8,  8, 10, 10, 99, 99, 99},
+    {-10,-10,-10,-10,-10,-10, -5, -5, -5,  0,  0,  0,  0,  0, 99, 99, 99},
+    {-30,-30,-30,-30,-30,-24,-20,-14,-10, -6, -8, -8, -6, -6, 99, 99, 99}}},
+
+  {{{-15,-15,-15,-15,-15,-12,-10, -8,  0,  2,  4,  4,  5,  5, 99, 99, 99},
+    {-30,-30,-30,-30,-26,-22,-20,-14,-12,-12,-10,-10,-10,-10, 99, 99, 99},
+    {-30,-30,-30,-30,-26,-26,-26,-26,-26,-26,-26,-26,-26,-24, 99, 99, 99}}},
+};
+
+/* stereo mode by base quality level */
+static const adj_stereo _psy_stereo_modes_8[3]={
+  /*  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  */
+  {{  4,  4,  4,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3},
+   {  6,  5,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
+   {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+  {{  4,  4,  4,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3},
+   {  6,  5,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
+   {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+  {{  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3},
+   {  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4},
+   {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1},
+   { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}},
+};
+
+static const noiseguard _psy_noiseguards_8[2]={
+  {10,10,-1},
+  {10,10,-1},
+};
+
+static const compandblock _psy_compand_8[2]={
+  {{
+     0, 1, 2, 3, 4, 5, 6,  7,     /* 7dB */
+     8, 8, 9, 9,10,10,11, 11,     /* 15dB */
+    12,12,13,13,14,14,15, 15,     /* 23dB */
+    16,16,17,17,17,18,18, 19,     /* 31dB */
+    19,19,20,21,22,23,24, 25,     /* 39dB */
+  }},
+  {{
+     0, 1, 2, 3, 4, 5, 6,  6,     /* 7dB */
+     7, 7, 6, 6, 5, 5, 4,  4,     /* 15dB */
+     3, 3, 3, 4, 5, 6, 7,  8,     /* 23dB */
+     9,10,11,12,13,14,15, 16,     /* 31dB */
+    17,18,19,20,21,22,23, 24,     /* 39dB */
+  }},
+};
+
+static const double _psy_lowpass_8[3]={3.,4.,4.};
+static const int _noise_start_8[2]={
+  64,64,
+};
+static const int _noise_part_8[2]={
+  8,8,
+};
+
+static const int _psy_ath_floater_8[3]={
+  -100,-100,-105,
+};
+
+static const int _psy_ath_abs_8[3]={
+  -130,-130,-140,
+};

+ 163 - 0
liboggvorbis/src/modes/residue_16.h

@@ -0,0 +1,163 @@
+/********************************************************************
+ *                                                                  *
+ * This FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: toplevel residue templates 16/22kHz
+ last mod: $Id: residue_16.h 16962 2010-03-11 07:30:34Z xiphmont $
+
+ ********************************************************************/
+
+/***** residue backends *********************************************/
+
+static const static_bookblock _resbook_16s_0={
+  {
+    {0},
+    {0,0,&_16c0_s_p1_0},
+    {0},
+    {0,0,&_16c0_s_p3_0},
+    {0,0,&_16c0_s_p4_0},
+    {0,0,&_16c0_s_p5_0},
+    {0,0,&_16c0_s_p6_0},
+    {&_16c0_s_p7_0,&_16c0_s_p7_1},
+    {&_16c0_s_p8_0,&_16c0_s_p8_1},
+    {&_16c0_s_p9_0,&_16c0_s_p9_1,&_16c0_s_p9_2}
+   }
+};
+static const static_bookblock _resbook_16s_1={
+  {
+    {0},
+    {0,0,&_16c1_s_p1_0},
+    {0},
+    {0,0,&_16c1_s_p3_0},
+    {0,0,&_16c1_s_p4_0},
+    {0,0,&_16c1_s_p5_0},
+    {0,0,&_16c1_s_p6_0},
+    {&_16c1_s_p7_0,&_16c1_s_p7_1},
+    {&_16c1_s_p8_0,&_16c1_s_p8_1},
+    {&_16c1_s_p9_0,&_16c1_s_p9_1,&_16c1_s_p9_2}
+   }
+};
+static const static_bookblock _resbook_16s_2={
+  {
+    {0},
+    {0,0,&_16c2_s_p1_0},
+    {0,0,&_16c2_s_p2_0},
+    {0,0,&_16c2_s_p3_0},
+    {0,0,&_16c2_s_p4_0},
+    {&_16c2_s_p5_0,&_16c2_s_p5_1},
+    {&_16c2_s_p6_0,&_16c2_s_p6_1},
+    {&_16c2_s_p7_0,&_16c2_s_p7_1},
+    {&_16c2_s_p8_0,&_16c2_s_p8_1},
+    {&_16c2_s_p9_0,&_16c2_s_p9_1,&_16c2_s_p9_2}
+   }
+};
+
+static const vorbis_residue_template _res_16s_0[]={
+  {2,0,32,  &_residue_44_mid,
+   &_huff_book__16c0_s_single,&_huff_book__16c0_s_single,
+   &_resbook_16s_0,&_resbook_16s_0},
+};
+static const vorbis_residue_template _res_16s_1[]={
+  {2,0,32,  &_residue_44_mid,
+   &_huff_book__16c1_s_short,&_huff_book__16c1_s_short,
+   &_resbook_16s_1,&_resbook_16s_1},
+
+  {2,0,32,  &_residue_44_mid,
+   &_huff_book__16c1_s_long,&_huff_book__16c1_s_long,
+   &_resbook_16s_1,&_resbook_16s_1}
+};
+static const vorbis_residue_template _res_16s_2[]={
+  {2,0,32,  &_residue_44_high,
+   &_huff_book__16c2_s_short,&_huff_book__16c2_s_short,
+   &_resbook_16s_2,&_resbook_16s_2},
+
+  {2,0,32,  &_residue_44_high,
+   &_huff_book__16c2_s_long,&_huff_book__16c2_s_long,
+   &_resbook_16s_2,&_resbook_16s_2}
+};
+
+static const vorbis_mapping_template _mapres_template_16_stereo[3]={
+  { _map_nominal, _res_16s_0 }, /* 0 */
+  { _map_nominal, _res_16s_1 }, /* 1 */
+  { _map_nominal, _res_16s_2 }, /* 2 */
+};
+
+static const static_bookblock _resbook_16u_0={
+  {
+    {0},
+    {0,0,&_16u0__p1_0},
+    {0,0,&_16u0__p2_0},
+    {0,0,&_16u0__p3_0},
+    {0,0,&_16u0__p4_0},
+    {0,0,&_16u0__p5_0},
+    {&_16u0__p6_0,&_16u0__p6_1},
+    {&_16u0__p7_0,&_16u0__p7_1,&_16u0__p7_2}
+   }
+};
+static const static_bookblock _resbook_16u_1={
+  {
+    {0},
+    {0,0,&_16u1__p1_0},
+    {0,0,&_16u1__p2_0},
+    {0,0,&_16u1__p3_0},
+    {0,0,&_16u1__p4_0},
+    {0,0,&_16u1__p5_0},
+    {0,0,&_16u1__p6_0},
+    {&_16u1__p7_0,&_16u1__p7_1},
+    {&_16u1__p8_0,&_16u1__p8_1},
+    {&_16u1__p9_0,&_16u1__p9_1,&_16u1__p9_2}
+   }
+};
+static const static_bookblock _resbook_16u_2={
+  {
+    {0},
+    {0,0,&_16u2_p1_0},
+    {0,0,&_16u2_p2_0},
+    {0,0,&_16u2_p3_0},
+    {0,0,&_16u2_p4_0},
+    {&_16u2_p5_0,&_16u2_p5_1},
+    {&_16u2_p6_0,&_16u2_p6_1},
+    {&_16u2_p7_0,&_16u2_p7_1},
+    {&_16u2_p8_0,&_16u2_p8_1},
+    {&_16u2_p9_0,&_16u2_p9_1,&_16u2_p9_2}
+   }
+};
+
+static const vorbis_residue_template _res_16u_0[]={
+  {1,0,32,  &_residue_44_low_un,
+   &_huff_book__16u0__single,&_huff_book__16u0__single,
+   &_resbook_16u_0,&_resbook_16u_0},
+};
+static const vorbis_residue_template _res_16u_1[]={
+  {1,0,32,  &_residue_44_mid_un,
+   &_huff_book__16u1__short,&_huff_book__16u1__short,
+   &_resbook_16u_1,&_resbook_16u_1},
+
+  {1,0,32,  &_residue_44_mid_un,
+   &_huff_book__16u1__long,&_huff_book__16u1__long,
+   &_resbook_16u_1,&_resbook_16u_1}
+};
+static const vorbis_residue_template _res_16u_2[]={
+  {1,0,32,  &_residue_44_hi_un,
+   &_huff_book__16u2__short,&_huff_book__16u2__short,
+   &_resbook_16u_2,&_resbook_16u_2},
+
+  {1,0,32,  &_residue_44_hi_un,
+   &_huff_book__16u2__long,&_huff_book__16u2__long,
+   &_resbook_16u_2,&_resbook_16u_2}
+};
+
+
+static const vorbis_mapping_template _mapres_template_16_uncoupled[3]={
+  { _map_nominal_u, _res_16u_0 }, /* 0 */
+  { _map_nominal_u, _res_16u_1 }, /* 1 */
+  { _map_nominal_u, _res_16u_2 }, /* 2 */
+};

+ 292 - 0
liboggvorbis/src/modes/residue_44.h

@@ -0,0 +1,292 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: toplevel residue templates for 32/44.1/48kHz
+ last mod: $Id: residue_44.h 16962 2010-03-11 07:30:34Z xiphmont $
+
+ ********************************************************************/
+
+#include "vorbis/codec.h"
+#include "backends.h"
+#include "books/coupled/res_books_stereo.h"
+
+/***** residue backends *********************************************/
+
+static const vorbis_info_residue0 _residue_44_low={
+  0,-1, -1, 9,-1,-1,
+  /* 0   1   2   3   4   5   6   7  */
+  {0},
+  {-1},
+  {  0,  1,  2,  2,  4,  8, 16, 32},
+  {  0,  0,  0,999,  4,  8, 16, 32},
+};
+
+static const vorbis_info_residue0 _residue_44_mid={
+  0,-1, -1, 10,-1,-1,
+  /* 0   1   2   3   4   5   6   7   8  */
+  {0},
+  {-1},
+  {  0,  1,  1,  2,  2,  4,  8, 16, 32},
+  {  0,  0,999,  0,999,  4,  8, 16, 32},
+};
+
+static const vorbis_info_residue0 _residue_44_high={
+  0,-1, -1, 10,-1,-1,
+  /* 0   1   2   3   4   5   6   7   8  */
+  {0},
+  {-1},
+  {  0,  1,  2,  4,  8, 16, 32, 71,157},
+  {  0,  1,  2,  3,  4,  8, 16, 71,157},
+};
+
+static const static_bookblock _resbook_44s_n1={
+  {
+    {0},{0,0,&_44cn1_s_p1_0},{0,0,&_44cn1_s_p2_0},
+    {0,0,&_44cn1_s_p3_0},{0,0,&_44cn1_s_p4_0},{0,0,&_44cn1_s_p5_0},
+    {&_44cn1_s_p6_0,&_44cn1_s_p6_1},{&_44cn1_s_p7_0,&_44cn1_s_p7_1},
+    {&_44cn1_s_p8_0,&_44cn1_s_p8_1,&_44cn1_s_p8_2}
+   }
+};
+static const static_bookblock _resbook_44sm_n1={
+  {
+    {0},{0,0,&_44cn1_sm_p1_0},{0,0,&_44cn1_sm_p2_0},
+    {0,0,&_44cn1_sm_p3_0},{0,0,&_44cn1_sm_p4_0},{0,0,&_44cn1_sm_p5_0},
+    {&_44cn1_sm_p6_0,&_44cn1_sm_p6_1},{&_44cn1_sm_p7_0,&_44cn1_sm_p7_1},
+    {&_44cn1_sm_p8_0,&_44cn1_sm_p8_1,&_44cn1_sm_p8_2}
+   }
+};
+
+static const static_bookblock _resbook_44s_0={
+  {
+    {0},{0,0,&_44c0_s_p1_0},{0,0,&_44c0_s_p2_0},
+    {0,0,&_44c0_s_p3_0},{0,0,&_44c0_s_p4_0},{0,0,&_44c0_s_p5_0},
+    {&_44c0_s_p6_0,&_44c0_s_p6_1},{&_44c0_s_p7_0,&_44c0_s_p7_1},
+    {&_44c0_s_p8_0,&_44c0_s_p8_1,&_44c0_s_p8_2}
+   }
+};
+static const static_bookblock _resbook_44sm_0={
+  {
+    {0},{0,0,&_44c0_sm_p1_0},{0,0,&_44c0_sm_p2_0},
+    {0,0,&_44c0_sm_p3_0},{0,0,&_44c0_sm_p4_0},{0,0,&_44c0_sm_p5_0},
+    {&_44c0_sm_p6_0,&_44c0_sm_p6_1},{&_44c0_sm_p7_0,&_44c0_sm_p7_1},
+    {&_44c0_sm_p8_0,&_44c0_sm_p8_1,&_44c0_sm_p8_2}
+   }
+};
+
+static const static_bookblock _resbook_44s_1={
+  {
+    {0},{0,0,&_44c1_s_p1_0},{0,0,&_44c1_s_p2_0},
+    {0,0,&_44c1_s_p3_0},{0,0,&_44c1_s_p4_0},{0,0,&_44c1_s_p5_0},
+    {&_44c1_s_p6_0,&_44c1_s_p6_1},{&_44c1_s_p7_0,&_44c1_s_p7_1},
+    {&_44c1_s_p8_0,&_44c1_s_p8_1,&_44c1_s_p8_2}
+   }
+};
+static const static_bookblock _resbook_44sm_1={
+  {
+    {0},{0,0,&_44c1_sm_p1_0},{0,0,&_44c1_sm_p2_0},
+    {0,0,&_44c1_sm_p3_0},{0,0,&_44c1_sm_p4_0},{0,0,&_44c1_sm_p5_0},
+    {&_44c1_sm_p6_0,&_44c1_sm_p6_1},{&_44c1_sm_p7_0,&_44c1_sm_p7_1},
+    {&_44c1_sm_p8_0,&_44c1_sm_p8_1,&_44c1_sm_p8_2}
+   }
+};
+
+static const static_bookblock _resbook_44s_2={
+  {
+    {0},{0,0,&_44c2_s_p1_0},{0,0,&_44c2_s_p2_0},{0,0,&_44c2_s_p3_0},
+    {0,0,&_44c2_s_p4_0},{0,0,&_44c2_s_p5_0},{0,0,&_44c2_s_p6_0},
+    {&_44c2_s_p7_0,&_44c2_s_p7_1},{&_44c2_s_p8_0,&_44c2_s_p8_1},
+    {&_44c2_s_p9_0,&_44c2_s_p9_1,&_44c2_s_p9_2}
+   }
+};
+static const static_bookblock _resbook_44s_3={
+  {
+    {0},{0,0,&_44c3_s_p1_0},{0,0,&_44c3_s_p2_0},{0,0,&_44c3_s_p3_0},
+    {0,0,&_44c3_s_p4_0},{0,0,&_44c3_s_p5_0},{0,0,&_44c3_s_p6_0},
+    {&_44c3_s_p7_0,&_44c3_s_p7_1},{&_44c3_s_p8_0,&_44c3_s_p8_1},
+    {&_44c3_s_p9_0,&_44c3_s_p9_1,&_44c3_s_p9_2}
+   }
+};
+static const static_bookblock _resbook_44s_4={
+  {
+    {0},{0,0,&_44c4_s_p1_0},{0,0,&_44c4_s_p2_0},{0,0,&_44c4_s_p3_0},
+    {0,0,&_44c4_s_p4_0},{0,0,&_44c4_s_p5_0},{0,0,&_44c4_s_p6_0},
+    {&_44c4_s_p7_0,&_44c4_s_p7_1},{&_44c4_s_p8_0,&_44c4_s_p8_1},
+    {&_44c4_s_p9_0,&_44c4_s_p9_1,&_44c4_s_p9_2}
+   }
+};
+static const static_bookblock _resbook_44s_5={
+  {
+    {0},{0,0,&_44c5_s_p1_0},{0,0,&_44c5_s_p2_0},{0,0,&_44c5_s_p3_0},
+    {0,0,&_44c5_s_p4_0},{0,0,&_44c5_s_p5_0},{0,0,&_44c5_s_p6_0},
+    {&_44c5_s_p7_0,&_44c5_s_p7_1},{&_44c5_s_p8_0,&_44c5_s_p8_1},
+    {&_44c5_s_p9_0,&_44c5_s_p9_1,&_44c5_s_p9_2}
+   }
+};
+static const static_bookblock _resbook_44s_6={
+  {
+    {0},{0,0,&_44c6_s_p1_0},{0,0,&_44c6_s_p2_0},{0,0,&_44c6_s_p3_0},
+    {0,0,&_44c6_s_p4_0},
+    {&_44c6_s_p5_0,&_44c6_s_p5_1},
+    {&_44c6_s_p6_0,&_44c6_s_p6_1},
+    {&_44c6_s_p7_0,&_44c6_s_p7_1},
+    {&_44c6_s_p8_0,&_44c6_s_p8_1},
+    {&_44c6_s_p9_0,&_44c6_s_p9_1,&_44c6_s_p9_2}
+   }
+};
+static const static_bookblock _resbook_44s_7={
+  {
+    {0},{0,0,&_44c7_s_p1_0},{0,0,&_44c7_s_p2_0},{0,0,&_44c7_s_p3_0},
+    {0,0,&_44c7_s_p4_0},
+    {&_44c7_s_p5_0,&_44c7_s_p5_1},
+    {&_44c7_s_p6_0,&_44c7_s_p6_1},
+    {&_44c7_s_p7_0,&_44c7_s_p7_1},
+    {&_44c7_s_p8_0,&_44c7_s_p8_1},
+    {&_44c7_s_p9_0,&_44c7_s_p9_1,&_44c7_s_p9_2}
+   }
+};
+static const static_bookblock _resbook_44s_8={
+  {
+    {0},{0,0,&_44c8_s_p1_0},{0,0,&_44c8_s_p2_0},{0,0,&_44c8_s_p3_0},
+    {0,0,&_44c8_s_p4_0},
+    {&_44c8_s_p5_0,&_44c8_s_p5_1},
+    {&_44c8_s_p6_0,&_44c8_s_p6_1},
+    {&_44c8_s_p7_0,&_44c8_s_p7_1},
+    {&_44c8_s_p8_0,&_44c8_s_p8_1},
+    {&_44c8_s_p9_0,&_44c8_s_p9_1,&_44c8_s_p9_2}
+   }
+};
+static const static_bookblock _resbook_44s_9={
+  {
+    {0},{0,0,&_44c9_s_p1_0},{0,0,&_44c9_s_p2_0},{0,0,&_44c9_s_p3_0},
+    {0,0,&_44c9_s_p4_0},
+    {&_44c9_s_p5_0,&_44c9_s_p5_1},
+    {&_44c9_s_p6_0,&_44c9_s_p6_1},
+    {&_44c9_s_p7_0,&_44c9_s_p7_1},
+    {&_44c9_s_p8_0,&_44c9_s_p8_1},
+    {&_44c9_s_p9_0,&_44c9_s_p9_1,&_44c9_s_p9_2}
+   }
+};
+
+static const vorbis_residue_template _res_44s_n1[]={
+  {2,0,32,  &_residue_44_low,
+   &_huff_book__44cn1_s_short,&_huff_book__44cn1_sm_short,
+   &_resbook_44s_n1,&_resbook_44sm_n1},
+
+  {2,0,32,  &_residue_44_low,
+   &_huff_book__44cn1_s_long,&_huff_book__44cn1_sm_long,
+   &_resbook_44s_n1,&_resbook_44sm_n1}
+};
+static const vorbis_residue_template _res_44s_0[]={
+  {2,0,16,  &_residue_44_low,
+   &_huff_book__44c0_s_short,&_huff_book__44c0_sm_short,
+   &_resbook_44s_0,&_resbook_44sm_0},
+
+  {2,0,32,  &_residue_44_low,
+   &_huff_book__44c0_s_long,&_huff_book__44c0_sm_long,
+   &_resbook_44s_0,&_resbook_44sm_0}
+};
+static const vorbis_residue_template _res_44s_1[]={
+  {2,0,16,  &_residue_44_low,
+   &_huff_book__44c1_s_short,&_huff_book__44c1_sm_short,
+   &_resbook_44s_1,&_resbook_44sm_1},
+
+  {2,0,32,  &_residue_44_low,
+   &_huff_book__44c1_s_long,&_huff_book__44c1_sm_long,
+   &_resbook_44s_1,&_resbook_44sm_1}
+};
+
+static const vorbis_residue_template _res_44s_2[]={
+  {2,0,16,  &_residue_44_mid,
+   &_huff_book__44c2_s_short,&_huff_book__44c2_s_short,
+   &_resbook_44s_2,&_resbook_44s_2},
+
+  {2,0,32,  &_residue_44_mid,
+   &_huff_book__44c2_s_long,&_huff_book__44c2_s_long,
+   &_resbook_44s_2,&_resbook_44s_2}
+};
+static const vorbis_residue_template _res_44s_3[]={
+  {2,0,16,  &_residue_44_mid,
+   &_huff_book__44c3_s_short,&_huff_book__44c3_s_short,
+   &_resbook_44s_3,&_resbook_44s_3},
+
+  {2,0,32,  &_residue_44_mid,
+   &_huff_book__44c3_s_long,&_huff_book__44c3_s_long,
+   &_resbook_44s_3,&_resbook_44s_3}
+};
+static const vorbis_residue_template _res_44s_4[]={
+  {2,0,16,  &_residue_44_mid,
+   &_huff_book__44c4_s_short,&_huff_book__44c4_s_short,
+   &_resbook_44s_4,&_resbook_44s_4},
+
+  {2,0,32,  &_residue_44_mid,
+   &_huff_book__44c4_s_long,&_huff_book__44c4_s_long,
+   &_resbook_44s_4,&_resbook_44s_4}
+};
+static const vorbis_residue_template _res_44s_5[]={
+  {2,0,16,  &_residue_44_mid,
+   &_huff_book__44c5_s_short,&_huff_book__44c5_s_short,
+   &_resbook_44s_5,&_resbook_44s_5},
+
+  {2,0,32,  &_residue_44_mid,
+   &_huff_book__44c5_s_long,&_huff_book__44c5_s_long,
+   &_resbook_44s_5,&_resbook_44s_5}
+};
+static const vorbis_residue_template _res_44s_6[]={
+  {2,0,16,  &_residue_44_high,
+   &_huff_book__44c6_s_short,&_huff_book__44c6_s_short,
+   &_resbook_44s_6,&_resbook_44s_6},
+
+  {2,0,32,  &_residue_44_high,
+   &_huff_book__44c6_s_long,&_huff_book__44c6_s_long,
+   &_resbook_44s_6,&_resbook_44s_6}
+};
+static const vorbis_residue_template _res_44s_7[]={
+  {2,0,16,  &_residue_44_high,
+   &_huff_book__44c7_s_short,&_huff_book__44c7_s_short,
+   &_resbook_44s_7,&_resbook_44s_7},
+
+  {2,0,32,  &_residue_44_high,
+   &_huff_book__44c7_s_long,&_huff_book__44c7_s_long,
+   &_resbook_44s_7,&_resbook_44s_7}
+};
+static const vorbis_residue_template _res_44s_8[]={
+  {2,0,16,  &_residue_44_high,
+   &_huff_book__44c8_s_short,&_huff_book__44c8_s_short,
+   &_resbook_44s_8,&_resbook_44s_8},
+
+  {2,0,32,  &_residue_44_high,
+   &_huff_book__44c8_s_long,&_huff_book__44c8_s_long,
+   &_resbook_44s_8,&_resbook_44s_8}
+};
+static const vorbis_residue_template _res_44s_9[]={
+  {2,0,16,  &_residue_44_high,
+   &_huff_book__44c9_s_short,&_huff_book__44c9_s_short,
+   &_resbook_44s_9,&_resbook_44s_9},
+
+  {2,0,32,  &_residue_44_high,
+   &_huff_book__44c9_s_long,&_huff_book__44c9_s_long,
+   &_resbook_44s_9,&_resbook_44s_9}
+};
+
+static const vorbis_mapping_template _mapres_template_44_stereo[]={
+  { _map_nominal, _res_44s_n1 }, /* -1 */
+  { _map_nominal, _res_44s_0 }, /* 0 */
+  { _map_nominal, _res_44s_1 }, /* 1 */
+  { _map_nominal, _res_44s_2 }, /* 2 */
+  { _map_nominal, _res_44s_3 }, /* 3 */
+  { _map_nominal, _res_44s_4 }, /* 4 */
+  { _map_nominal, _res_44s_5 }, /* 5 */
+  { _map_nominal, _res_44s_6 }, /* 6 */
+  { _map_nominal, _res_44s_7 }, /* 7 */
+  { _map_nominal, _res_44s_8 }, /* 8 */
+  { _map_nominal, _res_44s_9 }, /* 9 */
+};

+ 451 - 0
liboggvorbis/src/modes/residue_44p51.h

@@ -0,0 +1,451 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: toplevel residue templates for 32/44.1/48kHz uncoupled
+ last mod: $Id: residue_44p51.h 19013 2013-11-12 04:04:50Z giles $
+
+ ********************************************************************/
+
+#include "vorbis/codec.h"
+#include "backends.h"
+
+#include "books/coupled/res_books_51.h"
+
+/***** residue backends *********************************************/
+
+static const vorbis_info_residue0 _residue_44p_lo={
+  0,-1, -1, 7,-1,-1,
+  /* 0   1   2   3   4   5   6   7   8  */
+  {0},
+  {-1},
+  {  0,  1,  2,  7, 17, 31},
+  {  0,  0, 99,  7, 17, 31},
+};
+
+static const vorbis_info_residue0 _residue_44p={
+  0,-1, -1, 8,-1,-1,
+  /* 0   1   2   3   4   5   6   7   8  */
+  {0},
+  {-1},
+  {  0,  1,  1,   2,  7, 17, 31},
+  {  0,  0, 99,  99,  7, 17, 31},
+};
+
+static const vorbis_info_residue0 _residue_44p_hi={
+  0,-1, -1, 8,-1,-1,
+  /* 0   1   2   3   4   5   6   7   8  */
+  {0},
+  {-1},
+  {  0,  1,  2,  4,  7, 17, 31},
+  {  0,  1,  2,  4,  7, 17, 31},
+};
+
+static const vorbis_info_residue0 _residue_44p_lfe={
+  0,-1, -1, 2,-1,-1,
+  /* 0   1   2   3   4   5   6   7   8  */
+  {0},
+  {-1},
+  { 32},
+  { -1}
+};
+
+static const static_bookblock _resbook_44p_n1={
+  {
+    {0},
+    {0,&_44pn1_p1_0},
+
+    {&_44pn1_p2_0,&_44pn1_p2_1,0},
+    {&_44pn1_p3_0,&_44pn1_p3_1,0},
+    {&_44pn1_p4_0,&_44pn1_p4_1,0},
+
+    {&_44pn1_p5_0,&_44pn1_p5_1,&_44pn1_p4_1},
+    {&_44pn1_p6_0,&_44pn1_p6_1,&_44pn1_p6_2},
+   }
+};
+
+static const static_bookblock _resbook_44p_0={
+  {
+    {0},
+    {0,&_44p0_p1_0},
+
+    {&_44p0_p2_0,&_44p0_p2_1,0},
+    {&_44p0_p3_0,&_44p0_p3_1,0},
+    {&_44p0_p4_0,&_44p0_p4_1,0},
+
+    {&_44p0_p5_0,&_44p0_p5_1,&_44p0_p4_1},
+    {&_44p0_p6_0,&_44p0_p6_1,&_44p0_p6_2},
+   }
+};
+
+static const static_bookblock _resbook_44p_1={
+  {
+    {0},
+    {0,&_44p1_p1_0},
+
+    {&_44p1_p2_0,&_44p1_p2_1,0},
+    {&_44p1_p3_0,&_44p1_p3_1,0},
+    {&_44p1_p4_0,&_44p1_p4_1,0},
+
+    {&_44p1_p5_0,&_44p1_p5_1,&_44p1_p4_1},
+    {&_44p1_p6_0,&_44p1_p6_1,&_44p1_p6_2},
+   }
+};
+
+static const static_bookblock _resbook_44p_2={
+  {
+    {0},
+    {0,0,&_44p2_p1_0},
+    {0,&_44p2_p2_0,0},
+
+    {&_44p2_p3_0,&_44p2_p3_1,0},
+    {&_44p2_p4_0,&_44p2_p4_1,0},
+    {&_44p2_p5_0,&_44p2_p5_1,0},
+
+    {&_44p2_p6_0,&_44p2_p6_1,&_44p2_p5_1},
+    {&_44p2_p7_0,&_44p2_p7_1,&_44p2_p7_2,&_44p2_p7_3}
+   }
+};
+static const static_bookblock _resbook_44p_3={
+  {
+    {0},
+    {0,0,&_44p3_p1_0},
+    {0,&_44p3_p2_0,0},
+
+    {&_44p3_p3_0,&_44p3_p3_1,0},
+    {&_44p3_p4_0,&_44p3_p4_1,0},
+    {&_44p3_p5_0,&_44p3_p5_1,0},
+
+    {&_44p3_p6_0,&_44p3_p6_1,&_44p3_p5_1},
+    {&_44p3_p7_0,&_44p3_p7_1,&_44p3_p7_2,&_44p3_p7_3}
+   }
+};
+static const static_bookblock _resbook_44p_4={
+  {
+    {0},
+    {0,0,&_44p4_p1_0},
+    {0,&_44p4_p2_0,0},
+
+    {&_44p4_p3_0,&_44p4_p3_1,0},
+    {&_44p4_p4_0,&_44p4_p4_1,0},
+    {&_44p4_p5_0,&_44p4_p5_1,0},
+
+    {&_44p4_p6_0,&_44p4_p6_1,&_44p4_p5_1},
+    {&_44p4_p7_0,&_44p4_p7_1,&_44p4_p7_2,&_44p4_p7_3}
+   }
+};
+static const static_bookblock _resbook_44p_5={
+  {
+    {0},
+    {0,0,&_44p5_p1_0},
+    {0,&_44p5_p2_0,0},
+
+    {&_44p5_p3_0,&_44p5_p3_1,0},
+    {&_44p5_p4_0,&_44p5_p4_1,0},
+    {&_44p5_p5_0,&_44p5_p5_1,0},
+
+    {&_44p5_p6_0,&_44p5_p6_1,&_44p5_p5_1},
+    {&_44p5_p7_0,&_44p5_p7_1,&_44p5_p7_2,&_44p5_p7_3}
+   }
+};
+static const static_bookblock _resbook_44p_6={
+  {
+    {0},
+    {0,0,&_44p6_p1_0},
+    {0,&_44p6_p2_0,0},
+
+    {&_44p6_p3_0,&_44p6_p3_1,0},
+    {&_44p6_p4_0,&_44p6_p4_1,0},
+    {&_44p6_p5_0,&_44p6_p5_1,0},
+
+    {&_44p6_p6_0,&_44p6_p6_1,&_44p6_p5_1},
+    {&_44p6_p7_0,&_44p6_p7_1,&_44p6_p7_2,&_44p6_p7_3}
+   }
+};
+static const static_bookblock _resbook_44p_7={
+  {
+    {0},
+    {0,0,&_44p7_p1_0},
+    {0,&_44p7_p2_0,0},
+
+    {&_44p7_p3_0,&_44p7_p3_1,0},
+    {&_44p7_p4_0,&_44p7_p4_1,0},
+    {&_44p7_p5_0,&_44p7_p5_1,0},
+
+    {&_44p7_p6_0,&_44p7_p6_1,&_44p7_p5_1},
+    {&_44p7_p7_0,&_44p7_p7_1,&_44p7_p7_2,&_44p7_p7_3}
+   }
+};
+static const static_bookblock _resbook_44p_8={
+  {
+    {0},
+    {0,0,&_44p8_p1_0},
+    {0,&_44p8_p2_0,0},
+
+    {&_44p8_p3_0,&_44p8_p3_1,0},
+    {&_44p8_p4_0,&_44p8_p4_1,0},
+    {&_44p8_p5_0,&_44p8_p5_1,0},
+
+    {&_44p8_p6_0,&_44p8_p6_1,&_44p8_p5_1},
+    {&_44p8_p7_0,&_44p8_p7_1,&_44p8_p7_2,&_44p8_p7_3}
+   }
+};
+static const static_bookblock _resbook_44p_9={
+  {
+    {0},
+    {0,0,&_44p9_p1_0},
+    {0,&_44p9_p2_0,0},
+
+    {&_44p9_p3_0,&_44p9_p3_1,0},
+    {&_44p9_p4_0,&_44p9_p4_1,0},
+    {&_44p9_p5_0,&_44p9_p5_1,0},
+
+    {&_44p9_p6_0,&_44p9_p6_1,&_44p9_p5_1},
+    {&_44p9_p7_0,&_44p9_p7_1,&_44p9_p7_2,&_44p9_p7_3}
+   }
+};
+
+static const static_bookblock _resbook_44p_ln1={
+  {
+    {&_44pn1_l0_0,&_44pn1_l0_1,0},
+    {&_44pn1_l1_0,&_44pn1_p6_1,&_44pn1_p6_2},
+   }
+};
+static const static_bookblock _resbook_44p_l0={
+  {
+    {&_44p0_l0_0,&_44p0_l0_1,0},
+    {&_44p0_l1_0,&_44p0_p6_1,&_44p0_p6_2},
+   }
+};
+static const static_bookblock _resbook_44p_l1={
+  {
+    {&_44p1_l0_0,&_44p1_l0_1,0},
+    {&_44p1_l1_0,&_44p1_p6_1,&_44p1_p6_2},
+   }
+};
+static const static_bookblock _resbook_44p_l2={
+  {
+    {&_44p2_l0_0,&_44p2_l0_1,0},
+    {&_44p2_l1_0,&_44p2_p7_2,&_44p2_p7_3},
+   }
+};
+static const static_bookblock _resbook_44p_l3={
+  {
+    {&_44p3_l0_0,&_44p3_l0_1,0},
+    {&_44p3_l1_0,&_44p3_p7_2,&_44p3_p7_3},
+   }
+};
+static const static_bookblock _resbook_44p_l4={
+  {
+    {&_44p4_l0_0,&_44p4_l0_1,0},
+    {&_44p4_l1_0,&_44p4_p7_2,&_44p4_p7_3},
+   }
+};
+static const static_bookblock _resbook_44p_l5={
+  {
+    {&_44p5_l0_0,&_44p5_l0_1,0},
+    {&_44p5_l1_0,&_44p5_p7_2,&_44p5_p7_3},
+   }
+};
+static const static_bookblock _resbook_44p_l6={
+  {
+    {&_44p6_l0_0,&_44p6_l0_1,0},
+    {&_44p6_l1_0,&_44p6_p7_2,&_44p6_p7_3},
+   }
+};
+static const static_bookblock _resbook_44p_l7={
+  {
+    {&_44p7_l0_0,&_44p7_l0_1,0},
+    {&_44p7_l1_0,&_44p7_p7_2,&_44p7_p7_3},
+   }
+};
+static const static_bookblock _resbook_44p_l8={
+  {
+    {&_44p8_l0_0,&_44p8_l0_1,0},
+    {&_44p8_l1_0,&_44p8_p7_2,&_44p8_p7_3},
+   }
+};
+static const static_bookblock _resbook_44p_l9={
+  {
+    {&_44p9_l0_0,&_44p9_l0_1,0},
+    {&_44p9_l1_0,&_44p9_p7_2,&_44p9_p7_3},
+   }
+};
+
+
+static const vorbis_info_mapping0 _map_nominal_51[2]={
+  {2, {0,0,0,0,0,1}, {0,2}, {0,2}, 4,{0,3,0,0},{2,4,1,3}},
+  {2, {0,0,0,0,0,1}, {1,2}, {1,2}, 4,{0,3,0,0},{2,4,1,3}}
+};
+static const vorbis_info_mapping0 _map_nominal_51u[2]={
+  {2, {0,0,0,0,0,1}, {0,2}, {0,2}, 0,{0},{0}},
+  {2, {0,0,0,0,0,1}, {1,2}, {1,2}, 0,{0},{0}}
+};
+
+static const vorbis_residue_template _res_44p51_n1[]={
+  {2,0,30,  &_residue_44p_lo,
+   &_huff_book__44pn1_short,&_huff_book__44pn1_short,
+   &_resbook_44p_n1,&_resbook_44p_n1},
+
+  {2,0,30,  &_residue_44p_lo,
+   &_huff_book__44pn1_long,&_huff_book__44pn1_long,
+   &_resbook_44p_n1,&_resbook_44p_n1},
+
+  {1,2,6,  &_residue_44p_lfe,
+   &_huff_book__44pn1_lfe,&_huff_book__44pn1_lfe,
+   &_resbook_44p_ln1,&_resbook_44p_ln1}
+};
+static const vorbis_residue_template _res_44p51_0[]={
+  {2,0,15,  &_residue_44p_lo,
+   &_huff_book__44p0_short,&_huff_book__44p0_short,
+   &_resbook_44p_0,&_resbook_44p_0},
+
+  {2,0,30,  &_residue_44p_lo,
+   &_huff_book__44p0_long,&_huff_book__44p0_long,
+   &_resbook_44p_0,&_resbook_44p_0},
+
+  {1,2,6,  &_residue_44p_lfe,
+   &_huff_book__44p0_lfe,&_huff_book__44p0_lfe,
+   &_resbook_44p_l0,&_resbook_44p_l0}
+};
+static const vorbis_residue_template _res_44p51_1[]={
+  {2,0,15,  &_residue_44p_lo,
+   &_huff_book__44p1_short,&_huff_book__44p1_short,
+   &_resbook_44p_1,&_resbook_44p_1},
+
+  {2,0,30,  &_residue_44p_lo,
+   &_huff_book__44p1_long,&_huff_book__44p1_long,
+   &_resbook_44p_1,&_resbook_44p_1},
+
+  {1,2,6,  &_residue_44p_lfe,
+   &_huff_book__44p1_lfe,&_huff_book__44p1_lfe,
+   &_resbook_44p_l1,&_resbook_44p_l1}
+};
+static const vorbis_residue_template _res_44p51_2[]={
+  {2,0,15,  &_residue_44p,
+   &_huff_book__44p2_short,&_huff_book__44p2_short,
+   &_resbook_44p_2,&_resbook_44p_2},
+
+  {2,0,30,  &_residue_44p,
+   &_huff_book__44p2_long,&_huff_book__44p2_long,
+   &_resbook_44p_2,&_resbook_44p_2},
+
+  {1,2,6,  &_residue_44p_lfe,
+   &_huff_book__44p2_lfe,&_huff_book__44p2_lfe,
+   &_resbook_44p_l2,&_resbook_44p_l2}
+};
+static const vorbis_residue_template _res_44p51_3[]={
+  {2,0,15,  &_residue_44p,
+   &_huff_book__44p3_short,&_huff_book__44p3_short,
+   &_resbook_44p_3,&_resbook_44p_3},
+
+  {2,0,30,  &_residue_44p,
+   &_huff_book__44p3_long,&_huff_book__44p3_long,
+   &_resbook_44p_3,&_resbook_44p_3},
+
+  {1,2,6,  &_residue_44p_lfe,
+   &_huff_book__44p3_lfe,&_huff_book__44p3_lfe,
+   &_resbook_44p_l3,&_resbook_44p_l3}
+};
+static const vorbis_residue_template _res_44p51_4[]={
+  {2,0,15,  &_residue_44p,
+   &_huff_book__44p4_short,&_huff_book__44p4_short,
+   &_resbook_44p_4,&_resbook_44p_4},
+
+  {2,0,30,  &_residue_44p,
+   &_huff_book__44p4_long,&_huff_book__44p4_long,
+   &_resbook_44p_4,&_resbook_44p_4},
+
+  {1,2,6,  &_residue_44p_lfe,
+   &_huff_book__44p4_lfe,&_huff_book__44p4_lfe,
+   &_resbook_44p_l4,&_resbook_44p_l4}
+};
+static const vorbis_residue_template _res_44p51_5[]={
+  {2,0,15,  &_residue_44p_hi,
+   &_huff_book__44p5_short,&_huff_book__44p5_short,
+   &_resbook_44p_5,&_resbook_44p_5},
+
+  {2,0,30,  &_residue_44p_hi,
+   &_huff_book__44p5_long,&_huff_book__44p5_long,
+   &_resbook_44p_5,&_resbook_44p_5},
+
+  {1,2,6,  &_residue_44p_lfe,
+   &_huff_book__44p5_lfe,&_huff_book__44p5_lfe,
+   &_resbook_44p_l5,&_resbook_44p_l5}
+};
+static const vorbis_residue_template _res_44p51_6[]={
+  {2,0,15,  &_residue_44p_hi,
+   &_huff_book__44p6_short,&_huff_book__44p6_short,
+   &_resbook_44p_6,&_resbook_44p_6},
+
+  {2,0,30,  &_residue_44p_hi,
+   &_huff_book__44p6_long,&_huff_book__44p6_long,
+   &_resbook_44p_6,&_resbook_44p_6},
+
+  {1,2,6,  &_residue_44p_lfe,
+   &_huff_book__44p6_lfe,&_huff_book__44p6_lfe,
+   &_resbook_44p_l6,&_resbook_44p_l6}
+};
+
+
+static const vorbis_residue_template _res_44p51_7[]={
+  {2,0,15,  &_residue_44p_hi,
+   &_huff_book__44p7_short,&_huff_book__44p7_short,
+   &_resbook_44p_7,&_resbook_44p_7},
+
+  {2,0,30,  &_residue_44p_hi,
+   &_huff_book__44p7_long,&_huff_book__44p7_long,
+   &_resbook_44p_7,&_resbook_44p_7},
+
+  {1,2,6,  &_residue_44p_lfe,
+   &_huff_book__44p6_lfe,&_huff_book__44p6_lfe,
+   &_resbook_44p_l6,&_resbook_44p_l6}
+};
+static const vorbis_residue_template _res_44p51_8[]={
+  {2,0,15,  &_residue_44p_hi,
+   &_huff_book__44p8_short,&_huff_book__44p8_short,
+   &_resbook_44p_8,&_resbook_44p_8},
+
+  {2,0,30,  &_residue_44p_hi,
+   &_huff_book__44p8_long,&_huff_book__44p8_long,
+   &_resbook_44p_8,&_resbook_44p_8},
+
+  {1,2,6,  &_residue_44p_lfe,
+   &_huff_book__44p6_lfe,&_huff_book__44p6_lfe,
+   &_resbook_44p_l6,&_resbook_44p_l6}
+};
+static const vorbis_residue_template _res_44p51_9[]={
+  {2,0,15,  &_residue_44p_hi,
+   &_huff_book__44p9_short,&_huff_book__44p9_short,
+   &_resbook_44p_9,&_resbook_44p_9},
+
+  {2,0,30,  &_residue_44p_hi,
+   &_huff_book__44p9_long,&_huff_book__44p9_long,
+   &_resbook_44p_9,&_resbook_44p_9},
+
+  {1,2,6,  &_residue_44p_lfe,
+   &_huff_book__44p6_lfe,&_huff_book__44p6_lfe,
+   &_resbook_44p_l6,&_resbook_44p_l6}
+};
+
+static const vorbis_mapping_template _mapres_template_44_51[]={
+  { _map_nominal_51, _res_44p51_n1 }, /* -1 */
+  { _map_nominal_51, _res_44p51_0 }, /* 0 */
+  { _map_nominal_51, _res_44p51_1 }, /* 1 */
+  { _map_nominal_51, _res_44p51_2 }, /* 2 */
+  { _map_nominal_51, _res_44p51_3 }, /* 3 */
+  { _map_nominal_51, _res_44p51_4 }, /* 4 */
+  { _map_nominal_51u, _res_44p51_5 }, /* 5 */
+  { _map_nominal_51u, _res_44p51_6 }, /* 6 */
+  { _map_nominal_51u, _res_44p51_7 }, /* 7 */
+  { _map_nominal_51u, _res_44p51_8 }, /* 8 */
+  { _map_nominal_51u, _res_44p51_9 }, /* 9 */
+};

+ 318 - 0
liboggvorbis/src/modes/residue_44u.h

@@ -0,0 +1,318 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: toplevel residue templates for 32/44.1/48kHz uncoupled
+ last mod: $Id: residue_44u.h 16962 2010-03-11 07:30:34Z xiphmont $
+
+ ********************************************************************/
+
+#include "vorbis/codec.h"
+#include "backends.h"
+#include "books/uncoupled/res_books_uncoupled.h"
+
+/***** residue backends *********************************************/
+
+
+static const vorbis_info_residue0 _residue_44_low_un={
+  0,-1, -1, 8,-1,-1,
+  {0},
+  {-1},
+  {  0,  1,  1,  2,  2,  4, 28},
+  { -1, 25, -1, 45, -1, -1, -1}
+};
+
+static const vorbis_info_residue0 _residue_44_mid_un={
+  0,-1, -1, 10,-1,-1,
+  /* 0   1   2   3   4   5   6   7   8   9 */
+  {0},
+  {-1},
+  {  0,  1,  1,  2,  2,  4,  4, 16, 60},
+  { -1, 30, -1, 50, -1, 80, -1, -1, -1}
+};
+
+static const vorbis_info_residue0 _residue_44_hi_un={
+  0,-1, -1, 10,-1,-1,
+  /* 0   1   2   3   4   5   6   7   8   9 */
+  {0},
+  {-1},
+  {  0,  1,  2,  4,  8, 16, 32, 71,157},
+  { -1, -1, -1, -1, -1, -1, -1, -1, -1}
+};
+
+/* mapping conventions:
+   only one submap (this would change for efficient 5.1 support for example)*/
+/* Four psychoacoustic profiles are used, one for each blocktype */
+static const vorbis_info_mapping0 _map_nominal_u[2]={
+  {1, {0,0,0,0,0,0}, {0}, {0}, 0,{0},{0}},
+  {1, {0,0,0,0,0,0}, {1}, {1}, 0,{0},{0}}
+};
+
+static const static_bookblock _resbook_44u_n1={
+  {
+    {0},
+    {0,0,&_44un1__p1_0},
+    {0,0,&_44un1__p2_0},
+    {0,0,&_44un1__p3_0},
+    {0,0,&_44un1__p4_0},
+    {0,0,&_44un1__p5_0},
+    {&_44un1__p6_0,&_44un1__p6_1},
+    {&_44un1__p7_0,&_44un1__p7_1,&_44un1__p7_2}
+   }
+};
+static const static_bookblock _resbook_44u_0={
+  {
+    {0},
+    {0,0,&_44u0__p1_0},
+    {0,0,&_44u0__p2_0},
+    {0,0,&_44u0__p3_0},
+    {0,0,&_44u0__p4_0},
+    {0,0,&_44u0__p5_0},
+    {&_44u0__p6_0,&_44u0__p6_1},
+    {&_44u0__p7_0,&_44u0__p7_1,&_44u0__p7_2}
+   }
+};
+static const static_bookblock _resbook_44u_1={
+  {
+    {0},
+    {0,0,&_44u1__p1_0},
+    {0,0,&_44u1__p2_0},
+    {0,0,&_44u1__p3_0},
+    {0,0,&_44u1__p4_0},
+    {0,0,&_44u1__p5_0},
+    {&_44u1__p6_0,&_44u1__p6_1},
+    {&_44u1__p7_0,&_44u1__p7_1,&_44u1__p7_2}
+   }
+};
+static const static_bookblock _resbook_44u_2={
+  {
+    {0},
+    {0,0,&_44u2__p1_0},
+    {0,0,&_44u2__p2_0},
+    {0,0,&_44u2__p3_0},
+    {0,0,&_44u2__p4_0},
+    {0,0,&_44u2__p5_0},
+    {&_44u2__p6_0,&_44u2__p6_1},
+    {&_44u2__p7_0,&_44u2__p7_1,&_44u2__p7_2}
+   }
+};
+static const static_bookblock _resbook_44u_3={
+  {
+    {0},
+    {0,0,&_44u3__p1_0},
+    {0,0,&_44u3__p2_0},
+    {0,0,&_44u3__p3_0},
+    {0,0,&_44u3__p4_0},
+    {0,0,&_44u3__p5_0},
+    {&_44u3__p6_0,&_44u3__p6_1},
+    {&_44u3__p7_0,&_44u3__p7_1,&_44u3__p7_2}
+   }
+};
+static const static_bookblock _resbook_44u_4={
+  {
+    {0},
+    {0,0,&_44u4__p1_0},
+    {0,0,&_44u4__p2_0},
+    {0,0,&_44u4__p3_0},
+    {0,0,&_44u4__p4_0},
+    {0,0,&_44u4__p5_0},
+    {&_44u4__p6_0,&_44u4__p6_1},
+    {&_44u4__p7_0,&_44u4__p7_1,&_44u4__p7_2}
+   }
+};
+static const static_bookblock _resbook_44u_5={
+  {
+    {0},
+    {0,0,&_44u5__p1_0},
+    {0,0,&_44u5__p2_0},
+    {0,0,&_44u5__p3_0},
+    {0,0,&_44u5__p4_0},
+    {0,0,&_44u5__p5_0},
+    {0,0,&_44u5__p6_0},
+    {&_44u5__p7_0,&_44u5__p7_1},
+    {&_44u5__p8_0,&_44u5__p8_1},
+    {&_44u5__p9_0,&_44u5__p9_1,&_44u5__p9_2}
+   }
+};
+static const static_bookblock _resbook_44u_6={
+  {
+    {0},
+    {0,0,&_44u6__p1_0},
+    {0,0,&_44u6__p2_0},
+    {0,0,&_44u6__p3_0},
+    {0,0,&_44u6__p4_0},
+    {0,0,&_44u6__p5_0},
+    {0,0,&_44u6__p6_0},
+    {&_44u6__p7_0,&_44u6__p7_1},
+    {&_44u6__p8_0,&_44u6__p8_1},
+    {&_44u6__p9_0,&_44u6__p9_1,&_44u6__p9_2}
+   }
+};
+static const static_bookblock _resbook_44u_7={
+  {
+    {0},
+    {0,0,&_44u7__p1_0},
+    {0,0,&_44u7__p2_0},
+    {0,0,&_44u7__p3_0},
+    {0,0,&_44u7__p4_0},
+    {0,0,&_44u7__p5_0},
+    {0,0,&_44u7__p6_0},
+    {&_44u7__p7_0,&_44u7__p7_1},
+    {&_44u7__p8_0,&_44u7__p8_1},
+    {&_44u7__p9_0,&_44u7__p9_1,&_44u7__p9_2}
+   }
+};
+static const static_bookblock _resbook_44u_8={
+  {
+    {0},
+    {0,0,&_44u8_p1_0},
+    {0,0,&_44u8_p2_0},
+    {0,0,&_44u8_p3_0},
+    {0,0,&_44u8_p4_0},
+    {&_44u8_p5_0,&_44u8_p5_1},
+    {&_44u8_p6_0,&_44u8_p6_1},
+    {&_44u8_p7_0,&_44u8_p7_1},
+    {&_44u8_p8_0,&_44u8_p8_1},
+    {&_44u8_p9_0,&_44u8_p9_1,&_44u8_p9_2}
+   }
+};
+static const static_bookblock _resbook_44u_9={
+  {
+    {0},
+    {0,0,&_44u9_p1_0},
+    {0,0,&_44u9_p2_0},
+    {0,0,&_44u9_p3_0},
+    {0,0,&_44u9_p4_0},
+    {&_44u9_p5_0,&_44u9_p5_1},
+    {&_44u9_p6_0,&_44u9_p6_1},
+    {&_44u9_p7_0,&_44u9_p7_1},
+    {&_44u9_p8_0,&_44u9_p8_1},
+    {&_44u9_p9_0,&_44u9_p9_1,&_44u9_p9_2}
+   }
+};
+
+static const vorbis_residue_template _res_44u_n1[]={
+  {1,0,32,  &_residue_44_low_un,
+   &_huff_book__44un1__short,&_huff_book__44un1__short,
+   &_resbook_44u_n1,&_resbook_44u_n1},
+
+  {1,0,32,  &_residue_44_low_un,
+   &_huff_book__44un1__long,&_huff_book__44un1__long,
+   &_resbook_44u_n1,&_resbook_44u_n1}
+};
+static const vorbis_residue_template _res_44u_0[]={
+  {1,0,16,  &_residue_44_low_un,
+   &_huff_book__44u0__short,&_huff_book__44u0__short,
+   &_resbook_44u_0,&_resbook_44u_0},
+
+  {1,0,32,  &_residue_44_low_un,
+   &_huff_book__44u0__long,&_huff_book__44u0__long,
+   &_resbook_44u_0,&_resbook_44u_0}
+};
+static const vorbis_residue_template _res_44u_1[]={
+  {1,0,16,  &_residue_44_low_un,
+   &_huff_book__44u1__short,&_huff_book__44u1__short,
+   &_resbook_44u_1,&_resbook_44u_1},
+
+  {1,0,32,  &_residue_44_low_un,
+   &_huff_book__44u1__long,&_huff_book__44u1__long,
+   &_resbook_44u_1,&_resbook_44u_1}
+};
+static const vorbis_residue_template _res_44u_2[]={
+  {1,0,16,  &_residue_44_low_un,
+   &_huff_book__44u2__short,&_huff_book__44u2__short,
+   &_resbook_44u_2,&_resbook_44u_2},
+
+  {1,0,32,  &_residue_44_low_un,
+   &_huff_book__44u2__long,&_huff_book__44u2__long,
+   &_resbook_44u_2,&_resbook_44u_2}
+};
+static const vorbis_residue_template _res_44u_3[]={
+  {1,0,16,  &_residue_44_low_un,
+   &_huff_book__44u3__short,&_huff_book__44u3__short,
+   &_resbook_44u_3,&_resbook_44u_3},
+
+  {1,0,32,  &_residue_44_low_un,
+   &_huff_book__44u3__long,&_huff_book__44u3__long,
+   &_resbook_44u_3,&_resbook_44u_3}
+};
+static const vorbis_residue_template _res_44u_4[]={
+  {1,0,16,  &_residue_44_low_un,
+   &_huff_book__44u4__short,&_huff_book__44u4__short,
+   &_resbook_44u_4,&_resbook_44u_4},
+
+  {1,0,32,  &_residue_44_low_un,
+   &_huff_book__44u4__long,&_huff_book__44u4__long,
+   &_resbook_44u_4,&_resbook_44u_4}
+};
+
+static const vorbis_residue_template _res_44u_5[]={
+  {1,0,16,  &_residue_44_mid_un,
+   &_huff_book__44u5__short,&_huff_book__44u5__short,
+   &_resbook_44u_5,&_resbook_44u_5},
+
+  {1,0,32,  &_residue_44_mid_un,
+   &_huff_book__44u5__long,&_huff_book__44u5__long,
+   &_resbook_44u_5,&_resbook_44u_5}
+};
+
+static const vorbis_residue_template _res_44u_6[]={
+  {1,0,16,  &_residue_44_mid_un,
+   &_huff_book__44u6__short,&_huff_book__44u6__short,
+   &_resbook_44u_6,&_resbook_44u_6},
+
+  {1,0,32,  &_residue_44_mid_un,
+   &_huff_book__44u6__long,&_huff_book__44u6__long,
+   &_resbook_44u_6,&_resbook_44u_6}
+};
+
+static const vorbis_residue_template _res_44u_7[]={
+  {1,0,16,  &_residue_44_mid_un,
+   &_huff_book__44u7__short,&_huff_book__44u7__short,
+   &_resbook_44u_7,&_resbook_44u_7},
+
+  {1,0,32,  &_residue_44_mid_un,
+   &_huff_book__44u7__long,&_huff_book__44u7__long,
+   &_resbook_44u_7,&_resbook_44u_7}
+};
+
+static const vorbis_residue_template _res_44u_8[]={
+  {1,0,16,  &_residue_44_hi_un,
+   &_huff_book__44u8__short,&_huff_book__44u8__short,
+   &_resbook_44u_8,&_resbook_44u_8},
+
+  {1,0,32,  &_residue_44_hi_un,
+   &_huff_book__44u8__long,&_huff_book__44u8__long,
+   &_resbook_44u_8,&_resbook_44u_8}
+};
+static const vorbis_residue_template _res_44u_9[]={
+  {1,0,16,  &_residue_44_hi_un,
+   &_huff_book__44u9__short,&_huff_book__44u9__short,
+   &_resbook_44u_9,&_resbook_44u_9},
+
+  {1,0,32,  &_residue_44_hi_un,
+   &_huff_book__44u9__long,&_huff_book__44u9__long,
+   &_resbook_44u_9,&_resbook_44u_9}
+};
+
+static const vorbis_mapping_template _mapres_template_44_uncoupled[]={
+  { _map_nominal_u, _res_44u_n1 }, /* -1 */
+  { _map_nominal_u, _res_44u_0 }, /* 0 */
+  { _map_nominal_u, _res_44u_1 }, /* 1 */
+  { _map_nominal_u, _res_44u_2 }, /* 2 */
+  { _map_nominal_u, _res_44u_3 }, /* 3 */
+  { _map_nominal_u, _res_44u_4 }, /* 4 */
+  { _map_nominal_u, _res_44u_5 }, /* 5 */
+  { _map_nominal_u, _res_44u_6 }, /* 6 */
+  { _map_nominal_u, _res_44u_7 }, /* 7 */
+  { _map_nominal_u, _res_44u_8 }, /* 8 */
+  { _map_nominal_u, _res_44u_9 }, /* 9 */
+};

+ 109 - 0
liboggvorbis/src/modes/residue_8.h

@@ -0,0 +1,109 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: toplevel residue templates 8/11kHz
+ last mod: $Id: residue_8.h 16962 2010-03-11 07:30:34Z xiphmont $
+
+ ********************************************************************/
+
+#include "vorbis/codec.h"
+#include "backends.h"
+
+/***** residue backends *********************************************/
+
+static const static_bookblock _resbook_8s_0={
+  {
+    {0},
+    {0,0,&_8c0_s_p1_0},
+    {0},
+    {0,0,&_8c0_s_p3_0},
+    {0,0,&_8c0_s_p4_0},
+    {0,0,&_8c0_s_p5_0},
+    {0,0,&_8c0_s_p6_0},
+    {&_8c0_s_p7_0,&_8c0_s_p7_1},
+    {&_8c0_s_p8_0,&_8c0_s_p8_1},
+    {&_8c0_s_p9_0,&_8c0_s_p9_1,&_8c0_s_p9_2}
+   }
+};
+static const static_bookblock _resbook_8s_1={
+  {
+    {0},
+    {0,0,&_8c1_s_p1_0},
+    {0},
+    {0,0,&_8c1_s_p3_0},
+    {0,0,&_8c1_s_p4_0},
+    {0,0,&_8c1_s_p5_0},
+    {0,0,&_8c1_s_p6_0},
+    {&_8c1_s_p7_0,&_8c1_s_p7_1},
+    {&_8c1_s_p8_0,&_8c1_s_p8_1},
+    {&_8c1_s_p9_0,&_8c1_s_p9_1,&_8c1_s_p9_2}
+   }
+};
+
+static const vorbis_residue_template _res_8s_0[]={
+  {2,0,32,  &_residue_44_mid,
+   &_huff_book__8c0_s_single,&_huff_book__8c0_s_single,
+   &_resbook_8s_0,&_resbook_8s_0},
+};
+static const vorbis_residue_template _res_8s_1[]={
+  {2,0,32,  &_residue_44_mid,
+   &_huff_book__8c1_s_single,&_huff_book__8c1_s_single,
+   &_resbook_8s_1,&_resbook_8s_1},
+};
+
+static const vorbis_mapping_template _mapres_template_8_stereo[2]={
+  { _map_nominal, _res_8s_0 }, /* 0 */
+  { _map_nominal, _res_8s_1 }, /* 1 */
+};
+
+static const static_bookblock _resbook_8u_0={
+  {
+    {0},
+    {0,0,&_8u0__p1_0},
+    {0,0,&_8u0__p2_0},
+    {0,0,&_8u0__p3_0},
+    {0,0,&_8u0__p4_0},
+    {0,0,&_8u0__p5_0},
+    {&_8u0__p6_0,&_8u0__p6_1},
+    {&_8u0__p7_0,&_8u0__p7_1,&_8u0__p7_2}
+   }
+};
+static const static_bookblock _resbook_8u_1={
+  {
+    {0},
+    {0,0,&_8u1__p1_0},
+    {0,0,&_8u1__p2_0},
+    {0,0,&_8u1__p3_0},
+    {0,0,&_8u1__p4_0},
+    {0,0,&_8u1__p5_0},
+    {0,0,&_8u1__p6_0},
+    {&_8u1__p7_0,&_8u1__p7_1},
+    {&_8u1__p8_0,&_8u1__p8_1},
+    {&_8u1__p9_0,&_8u1__p9_1,&_8u1__p9_2}
+   }
+};
+
+static const vorbis_residue_template _res_8u_0[]={
+  {1,0,32,  &_residue_44_low_un,
+   &_huff_book__8u0__single,&_huff_book__8u0__single,
+   &_resbook_8u_0,&_resbook_8u_0},
+};
+static const vorbis_residue_template _res_8u_1[]={
+  {1,0,32,  &_residue_44_mid_un,
+   &_huff_book__8u1__single,&_huff_book__8u1__single,
+   &_resbook_8u_1,&_resbook_8u_1},
+};
+
+static const vorbis_mapping_template _mapres_template_8_uncoupled[2]={
+  { _map_nominal_u, _res_8u_0 }, /* 0 */
+  { _map_nominal_u, _res_8u_1 }, /* 1 */
+};

+ 143 - 0
liboggvorbis/src/modes/setup_11.h

@@ -0,0 +1,143 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: 11kHz settings
+ last mod: $Id: setup_11.h 16894 2010-02-12 20:32:12Z xiphmont $
+
+ ********************************************************************/
+
+#include "psych_11.h"
+
+static const int blocksize_11[2]={
+  512,512
+};
+
+static const int _floor_mapping_11a[]={
+  6,6
+};
+static const int *_floor_mapping_11[]={
+  _floor_mapping_11a
+};
+
+static const double rate_mapping_11[3]={
+  8000.,13000.,44000.,
+};
+
+static const double rate_mapping_11_uncoupled[3]={
+  12000.,20000.,50000.,
+};
+
+static const double quality_mapping_11[3]={
+  -.1,.0,1.
+};
+
+static const ve_setup_data_template ve_setup_11_stereo={
+  2,
+  rate_mapping_11,
+  quality_mapping_11,
+  2,
+  9000,
+  15000,
+
+  blocksize_11,
+  blocksize_11,
+
+  _psy_tone_masteratt_11,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_11,
+  NULL,
+  _vp_tonemask_adj_11,
+
+  _psy_noiseguards_8,
+  _psy_noisebias_11,
+  _psy_noisebias_11,
+  NULL,
+  NULL,
+  _psy_noise_suppress,
+
+  _psy_compand_8,
+  _psy_compand_8_mapping,
+  NULL,
+
+  {_noise_start_8,_noise_start_8},
+  {_noise_part_8,_noise_part_8},
+  _noise_thresh_11,
+
+  _psy_ath_floater_8,
+  _psy_ath_abs_8,
+
+  _psy_lowpass_11,
+
+  _psy_global_44,
+  _global_mapping_8,
+  _psy_stereo_modes_8,
+
+  _floor_books,
+  _floor,
+  1,
+  _floor_mapping_11,
+
+  _mapres_template_8_stereo
+};
+
+static const ve_setup_data_template ve_setup_11_uncoupled={
+  2,
+  rate_mapping_11_uncoupled,
+  quality_mapping_11,
+  -1,
+  9000,
+  15000,
+
+  blocksize_11,
+  blocksize_11,
+
+  _psy_tone_masteratt_11,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_11,
+  NULL,
+  _vp_tonemask_adj_11,
+
+  _psy_noiseguards_8,
+  _psy_noisebias_11,
+  _psy_noisebias_11,
+  NULL,
+  NULL,
+  _psy_noise_suppress,
+
+  _psy_compand_8,
+  _psy_compand_8_mapping,
+  NULL,
+
+  {_noise_start_8,_noise_start_8},
+  {_noise_part_8,_noise_part_8},
+  _noise_thresh_11,
+
+  _psy_ath_floater_8,
+  _psy_ath_abs_8,
+
+  _psy_lowpass_11,
+
+  _psy_global_44,
+  _global_mapping_8,
+  _psy_stereo_modes_8,
+
+  _floor_books,
+  _floor,
+  1,
+  _floor_mapping_11,
+
+  _mapres_template_8_uncoupled
+};

+ 153 - 0
liboggvorbis/src/modes/setup_16.h

@@ -0,0 +1,153 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: 16kHz settings
+ last mod: $Id: setup_16.h 16894 2010-02-12 20:32:12Z xiphmont $
+
+ ********************************************************************/
+
+#include "psych_16.h"
+#include "residue_16.h"
+
+static const int blocksize_16_short[3]={
+  1024,512,512
+};
+static const int blocksize_16_long[3]={
+  1024,1024,1024
+};
+
+static const int _floor_mapping_16a[]={
+  9,3,3
+};
+static const int _floor_mapping_16b[]={
+  9,9,9
+};
+static const int *_floor_mapping_16[]={
+  _floor_mapping_16a,
+  _floor_mapping_16b
+};
+
+static const double rate_mapping_16[4]={
+  12000.,20000.,44000.,86000.
+};
+
+static const double rate_mapping_16_uncoupled[4]={
+  16000.,28000.,64000.,100000.
+};
+
+static const double _global_mapping_16[4]={ 1., 2., 3., 4. };
+
+static const double quality_mapping_16[4]={ -.1,.05,.5,1. };
+
+static const double _psy_compand_16_mapping[4]={ 0., .8, 1., 1.};
+
+static const ve_setup_data_template ve_setup_16_stereo={
+  3,
+  rate_mapping_16,
+  quality_mapping_16,
+  2,
+  15000,
+  19000,
+
+  blocksize_16_short,
+  blocksize_16_long,
+
+  _psy_tone_masteratt_16,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_16,
+  _vp_tonemask_adj_16,
+  _vp_tonemask_adj_16,
+
+  _psy_noiseguards_16,
+  _psy_noisebias_16_impulse,
+  _psy_noisebias_16_short,
+  _psy_noisebias_16_short,
+  _psy_noisebias_16,
+  _psy_noise_suppress,
+
+  _psy_compand_8,
+  _psy_compand_16_mapping,
+  _psy_compand_16_mapping,
+
+  {_noise_start_16,_noise_start_16},
+  { _noise_part_16, _noise_part_16},
+  _noise_thresh_16,
+
+  _psy_ath_floater_16,
+  _psy_ath_abs_16,
+
+  _psy_lowpass_16,
+
+  _psy_global_44,
+  _global_mapping_16,
+  _psy_stereo_modes_16,
+
+  _floor_books,
+  _floor,
+  2,
+  _floor_mapping_16,
+
+  _mapres_template_16_stereo
+};
+
+static const ve_setup_data_template ve_setup_16_uncoupled={
+  3,
+  rate_mapping_16_uncoupled,
+  quality_mapping_16,
+  -1,
+  15000,
+  19000,
+
+  blocksize_16_short,
+  blocksize_16_long,
+
+  _psy_tone_masteratt_16,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_16,
+  _vp_tonemask_adj_16,
+  _vp_tonemask_adj_16,
+
+  _psy_noiseguards_16,
+  _psy_noisebias_16_impulse,
+  _psy_noisebias_16_short,
+  _psy_noisebias_16_short,
+  _psy_noisebias_16,
+  _psy_noise_suppress,
+
+  _psy_compand_8,
+  _psy_compand_16_mapping,
+  _psy_compand_16_mapping,
+
+  {_noise_start_16,_noise_start_16},
+  { _noise_part_16, _noise_part_16},
+  _noise_thresh_16,
+
+  _psy_ath_floater_16,
+  _psy_ath_abs_16,
+
+  _psy_lowpass_16,
+
+  _psy_global_44,
+  _global_mapping_16,
+  _psy_stereo_modes_16,
+
+  _floor_books,
+  _floor,
+  2,
+  _floor_mapping_16,
+
+  _mapres_template_16_uncoupled
+};

+ 128 - 0
liboggvorbis/src/modes/setup_22.h

@@ -0,0 +1,128 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: 22kHz settings
+ last mod: $Id: setup_22.h 17026 2010-03-25 05:00:27Z xiphmont $
+
+ ********************************************************************/
+
+static const double rate_mapping_22[4]={
+  15000.,20000.,44000.,86000.
+};
+
+static const double rate_mapping_22_uncoupled[4]={
+  16000.,28000.,50000.,90000.
+};
+
+static const double _psy_lowpass_22[4]={9.5,11.,30.,99.};
+
+static const ve_setup_data_template ve_setup_22_stereo={
+  3,
+  rate_mapping_22,
+  quality_mapping_16,
+  2,
+  19000,
+  26000,
+
+  blocksize_16_short,
+  blocksize_16_long,
+
+  _psy_tone_masteratt_16,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_16,
+  _vp_tonemask_adj_16,
+  _vp_tonemask_adj_16,
+
+  _psy_noiseguards_16,
+  _psy_noisebias_16_impulse,
+  _psy_noisebias_16_short,
+  _psy_noisebias_16_short,
+  _psy_noisebias_16,
+  _psy_noise_suppress,
+
+  _psy_compand_8,
+  _psy_compand_16_mapping,
+  _psy_compand_16_mapping,
+
+  {_noise_start_16,_noise_start_16},
+  { _noise_part_16, _noise_part_16},
+  _noise_thresh_16,
+
+  _psy_ath_floater_16,
+  _psy_ath_abs_16,
+
+  _psy_lowpass_22,
+
+  _psy_global_44,
+  _global_mapping_16,
+  _psy_stereo_modes_16,
+
+  _floor_books,
+  _floor,
+  2,
+  _floor_mapping_16,
+
+  _mapres_template_16_stereo
+};
+
+static const ve_setup_data_template ve_setup_22_uncoupled={
+  3,
+  rate_mapping_22_uncoupled,
+  quality_mapping_16,
+  -1,
+  19000,
+  26000,
+
+  blocksize_16_short,
+  blocksize_16_long,
+
+  _psy_tone_masteratt_16,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_16,
+  _vp_tonemask_adj_16,
+  _vp_tonemask_adj_16,
+
+  _psy_noiseguards_16,
+  _psy_noisebias_16_impulse,
+  _psy_noisebias_16_short,
+  _psy_noisebias_16_short,
+  _psy_noisebias_16,
+  _psy_noise_suppress,
+
+  _psy_compand_8,
+  _psy_compand_16_mapping,
+  _psy_compand_16_mapping,
+
+  {_noise_start_16,_noise_start_16},
+  { _noise_part_16, _noise_part_16},
+  _noise_thresh_16,
+
+  _psy_ath_floater_16,
+  _psy_ath_abs_16,
+
+  _psy_lowpass_22,
+
+  _psy_global_44,
+  _global_mapping_16,
+  _psy_stereo_modes_16,
+
+  _floor_books,
+  _floor,
+  2,
+  _floor_mapping_16,
+
+  _mapres_template_16_uncoupled
+};

+ 132 - 0
liboggvorbis/src/modes/setup_32.h

@@ -0,0 +1,132 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: toplevel settings for 32kHz
+ last mod: $Id: setup_32.h 16894 2010-02-12 20:32:12Z xiphmont $
+
+ ********************************************************************/
+
+static const double rate_mapping_32[12]={
+  18000.,28000.,35000.,45000.,56000.,60000.,
+  75000.,90000.,100000.,115000.,150000.,190000.,
+};
+
+static const double rate_mapping_32_un[12]={
+  30000.,42000.,52000.,64000.,72000.,78000.,
+  86000.,92000.,110000.,120000.,140000.,190000.,
+};
+
+static const double _psy_lowpass_32[12]={
+  12.3,13.,13.,14.,15.,99.,99.,99.,99.,99.,99.,99.
+};
+
+static const ve_setup_data_template ve_setup_32_stereo={
+  11,
+  rate_mapping_32,
+  quality_mapping_44,
+  2,
+  26000,
+  40000,
+
+  blocksize_short_44,
+  blocksize_long_44,
+
+  _psy_tone_masteratt_44,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_otherblock,
+  _vp_tonemask_adj_longblock,
+  _vp_tonemask_adj_otherblock,
+
+  _psy_noiseguards_44,
+  _psy_noisebias_impulse,
+  _psy_noisebias_padding,
+  _psy_noisebias_trans,
+  _psy_noisebias_long,
+  _psy_noise_suppress,
+
+  _psy_compand_44,
+  _psy_compand_short_mapping,
+  _psy_compand_long_mapping,
+
+  {_noise_start_short_44,_noise_start_long_44},
+  {_noise_part_short_44,_noise_part_long_44},
+  _noise_thresh_44,
+
+  _psy_ath_floater,
+  _psy_ath_abs,
+
+  _psy_lowpass_32,
+
+  _psy_global_44,
+  _global_mapping_44,
+  _psy_stereo_modes_44,
+
+  _floor_books,
+  _floor,
+  2,
+  _floor_mapping_44,
+
+  _mapres_template_44_stereo
+};
+
+static const ve_setup_data_template ve_setup_32_uncoupled={
+  11,
+  rate_mapping_32_un,
+  quality_mapping_44,
+  -1,
+  26000,
+  40000,
+
+  blocksize_short_44,
+  blocksize_long_44,
+
+  _psy_tone_masteratt_44,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_otherblock,
+  _vp_tonemask_adj_longblock,
+  _vp_tonemask_adj_otherblock,
+
+  _psy_noiseguards_44,
+  _psy_noisebias_impulse,
+  _psy_noisebias_padding,
+  _psy_noisebias_trans,
+  _psy_noisebias_long,
+  _psy_noise_suppress,
+
+  _psy_compand_44,
+  _psy_compand_short_mapping,
+  _psy_compand_long_mapping,
+
+  {_noise_start_short_44,_noise_start_long_44},
+  {_noise_part_short_44,_noise_part_long_44},
+  _noise_thresh_44,
+
+  _psy_ath_floater,
+  _psy_ath_abs,
+
+  _psy_lowpass_32,
+
+  _psy_global_44,
+  _global_mapping_44,
+  NULL,
+
+  _floor_books,
+  _floor,
+  2,
+  _floor_mapping_44,
+
+  _mapres_template_44_uncoupled
+};

+ 117 - 0
liboggvorbis/src/modes/setup_44.h

@@ -0,0 +1,117 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: toplevel settings for 44.1/48kHz
+ last mod: $Id: setup_44.h 16962 2010-03-11 07:30:34Z xiphmont $
+
+ ********************************************************************/
+
+#include "modes/floor_all.h"
+#include "modes/residue_44.h"
+#include "modes/psych_44.h"
+
+static const double rate_mapping_44_stereo[12]={
+  22500.,32000.,40000.,48000.,56000.,64000.,
+  80000.,96000.,112000.,128000.,160000.,250001.
+};
+
+static const double quality_mapping_44[12]={
+  -.1,.0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1.0
+};
+
+static const int blocksize_short_44[11]={
+  512,256,256,256,256,256,256,256,256,256,256
+};
+static const int blocksize_long_44[11]={
+  4096,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048
+};
+
+static const double _psy_compand_short_mapping[12]={
+  0.5, 1., 1., 1.3, 1.6, 2., 2., 2., 2., 2., 2., 2.
+};
+static const double _psy_compand_long_mapping[12]={
+  3.5, 4., 4., 4.3, 4.6, 5., 5., 5., 5., 5., 5., 5.
+};
+
+static const double _global_mapping_44[12]={
+  /* 1., 1., 1.5, 2., 2., 2.5, 2.7, 3.0, 3.5, 4., 4. */
+ 0., 1., 1., 1.5, 2., 2., 2.5, 2.7, 3.0, 3.7, 4., 4.
+};
+
+static const int _floor_mapping_44a[11]={
+  1,0,0,2,2,4,5,5,5,5,5
+};
+
+static const int _floor_mapping_44b[11]={
+  8,7,7,7,7,7,7,7,7,7,7
+};
+
+static const int _floor_mapping_44c[11]={
+  10,10,10,10,10,10,10,10,10,10,10
+};
+
+static const int *_floor_mapping_44[]={
+  _floor_mapping_44a,
+  _floor_mapping_44b,
+  _floor_mapping_44c,
+};
+
+static const ve_setup_data_template ve_setup_44_stereo={
+  11,
+  rate_mapping_44_stereo,
+  quality_mapping_44,
+  2,
+  40000,
+  50000,
+
+  blocksize_short_44,
+  blocksize_long_44,
+
+  _psy_tone_masteratt_44,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_otherblock,
+  _vp_tonemask_adj_longblock,
+  _vp_tonemask_adj_otherblock,
+
+  _psy_noiseguards_44,
+  _psy_noisebias_impulse,
+  _psy_noisebias_padding,
+  _psy_noisebias_trans,
+  _psy_noisebias_long,
+  _psy_noise_suppress,
+
+  _psy_compand_44,
+  _psy_compand_short_mapping,
+  _psy_compand_long_mapping,
+
+  {_noise_start_short_44,_noise_start_long_44},
+  {_noise_part_short_44,_noise_part_long_44},
+  _noise_thresh_44,
+
+  _psy_ath_floater,
+  _psy_ath_abs,
+
+  _psy_lowpass_44,
+
+  _psy_global_44,
+  _global_mapping_44,
+  _psy_stereo_modes_44,
+
+  _floor_books,
+  _floor,
+  2,
+  _floor_mapping_44,
+
+  _mapres_template_44_stereo
+};

+ 74 - 0
liboggvorbis/src/modes/setup_44p51.h

@@ -0,0 +1,74 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: toplevel settings for 44.1/48kHz 5.1 surround modes
+ last mod: $Id: setup_44p51.h 19013 2013-11-12 04:04:50Z giles $
+
+ ********************************************************************/
+
+#include "modes/residue_44p51.h"
+
+static const double rate_mapping_44p51[12]={
+  14000.,20000.,28000.,38000.,46000.,54000.,
+  75000.,96000.,120000.,140000.,180000.,240001.
+};
+
+static const ve_setup_data_template ve_setup_44_51={
+  11,
+  rate_mapping_44p51,
+  quality_mapping_44,
+  6,
+  40000,
+  70000,
+
+  blocksize_short_44,
+  blocksize_long_44,
+
+  _psy_tone_masteratt_44,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_otherblock,
+  _vp_tonemask_adj_longblock,
+  _vp_tonemask_adj_otherblock,
+
+  _psy_noiseguards_44,
+  _psy_noisebias_impulse,
+  _psy_noisebias_padding,
+  _psy_noisebias_trans,
+  _psy_noisebias_long,
+  _psy_noise_suppress,
+
+  _psy_compand_44,
+  _psy_compand_short_mapping,
+  _psy_compand_long_mapping,
+
+  {_noise_start_short_44,_noise_start_long_44},
+  {_noise_part_short_44,_noise_part_long_44},
+  _noise_thresh_44,
+
+  _psy_ath_floater,
+  _psy_ath_abs,
+
+  _psy_lowpass_44,
+
+  _psy_global_44,
+  _global_mapping_44,
+  _psy_stereo_modes_44,
+
+  _floor_books,
+  _floor,
+  3,
+  _floor_mapping_44,
+
+  _mapres_template_44_51
+};

+ 74 - 0
liboggvorbis/src/modes/setup_44u.h

@@ -0,0 +1,74 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: toplevel settings for 44.1/48kHz uncoupled modes
+ last mod: $Id: setup_44u.h 16962 2010-03-11 07:30:34Z xiphmont $
+
+ ********************************************************************/
+
+#include "modes/residue_44u.h"
+
+static const double rate_mapping_44_un[12]={
+  32000.,48000.,60000.,70000.,80000.,86000.,
+  96000.,110000.,120000.,140000.,160000.,240001.
+};
+
+static const ve_setup_data_template ve_setup_44_uncoupled={
+  11,
+  rate_mapping_44_un,
+  quality_mapping_44,
+  -1,
+  40000,
+  50000,
+
+  blocksize_short_44,
+  blocksize_long_44,
+
+  _psy_tone_masteratt_44,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_otherblock,
+  _vp_tonemask_adj_longblock,
+  _vp_tonemask_adj_otherblock,
+
+  _psy_noiseguards_44,
+  _psy_noisebias_impulse,
+  _psy_noisebias_padding,
+  _psy_noisebias_trans,
+  _psy_noisebias_long,
+  _psy_noise_suppress,
+
+  _psy_compand_44,
+  _psy_compand_short_mapping,
+  _psy_compand_long_mapping,
+
+  {_noise_start_short_44,_noise_start_long_44},
+  {_noise_part_short_44,_noise_part_long_44},
+  _noise_thresh_44,
+
+  _psy_ath_floater,
+  _psy_ath_abs,
+
+  _psy_lowpass_44,
+
+  _psy_global_44,
+  _global_mapping_44,
+  _psy_stereo_modes_44,
+
+  _floor_books,
+  _floor,
+  2,
+  _floor_mapping_44,
+
+  _mapres_template_44_uncoupled
+};

+ 149 - 0
liboggvorbis/src/modes/setup_8.h

@@ -0,0 +1,149 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: 8kHz settings
+ last mod: $Id: setup_8.h 16894 2010-02-12 20:32:12Z xiphmont $
+
+ ********************************************************************/
+
+#include "psych_8.h"
+#include "residue_8.h"
+
+static const int blocksize_8[2]={
+  512,512
+};
+
+static const int _floor_mapping_8a[]={
+  6,6
+};
+
+static const int *_floor_mapping_8[]={
+  _floor_mapping_8a
+};
+
+static const double rate_mapping_8[3]={
+  6000.,9000.,32000.,
+};
+
+static const double rate_mapping_8_uncoupled[3]={
+  8000.,14000.,42000.,
+};
+
+static const double quality_mapping_8[3]={
+  -.1,.0,1.
+};
+
+static const double _psy_compand_8_mapping[3]={ 0., 1., 1.};
+
+static const double _global_mapping_8[3]={ 1., 2., 3. };
+
+static const ve_setup_data_template ve_setup_8_stereo={
+  2,
+  rate_mapping_8,
+  quality_mapping_8,
+  2,
+  8000,
+  9000,
+
+  blocksize_8,
+  blocksize_8,
+
+  _psy_tone_masteratt_8,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_8,
+  NULL,
+  _vp_tonemask_adj_8,
+
+  _psy_noiseguards_8,
+  _psy_noisebias_8,
+  _psy_noisebias_8,
+  NULL,
+  NULL,
+  _psy_noise_suppress,
+
+  _psy_compand_8,
+  _psy_compand_8_mapping,
+  NULL,
+
+  {_noise_start_8,_noise_start_8},
+  {_noise_part_8,_noise_part_8},
+  _noise_thresh_5only,
+
+  _psy_ath_floater_8,
+  _psy_ath_abs_8,
+
+  _psy_lowpass_8,
+
+  _psy_global_44,
+  _global_mapping_8,
+  _psy_stereo_modes_8,
+
+  _floor_books,
+  _floor,
+  1,
+  _floor_mapping_8,
+
+  _mapres_template_8_stereo
+};
+
+static const ve_setup_data_template ve_setup_8_uncoupled={
+  2,
+  rate_mapping_8_uncoupled,
+  quality_mapping_8,
+  -1,
+  8000,
+  9000,
+
+  blocksize_8,
+  blocksize_8,
+
+  _psy_tone_masteratt_8,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_8,
+  NULL,
+  _vp_tonemask_adj_8,
+
+  _psy_noiseguards_8,
+  _psy_noisebias_8,
+  _psy_noisebias_8,
+  NULL,
+  NULL,
+  _psy_noise_suppress,
+
+  _psy_compand_8,
+  _psy_compand_8_mapping,
+  NULL,
+
+  {_noise_start_8,_noise_start_8},
+  {_noise_part_8,_noise_part_8},
+  _noise_thresh_5only,
+
+  _psy_ath_floater_8,
+  _psy_ath_abs_8,
+
+  _psy_lowpass_8,
+
+  _psy_global_44,
+  _global_mapping_8,
+  _psy_stereo_modes_8,
+
+  _floor_books,
+  _floor,
+  1,
+  _floor_mapping_8,
+
+  _mapres_template_8_uncoupled
+};

+ 225 - 0
liboggvorbis/src/modes/setup_X.h

@@ -0,0 +1,225 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: catch-all toplevel settings for q modes only
+ last mod: $Id: setup_X.h 16894 2010-02-12 20:32:12Z xiphmont $
+
+ ********************************************************************/
+
+static const double rate_mapping_X[12]={
+  -1.,-1.,-1.,-1.,-1.,-1.,
+  -1.,-1.,-1.,-1.,-1.,-1.
+};
+
+static const ve_setup_data_template ve_setup_X_stereo={
+  11,
+  rate_mapping_X,
+  quality_mapping_44,
+  2,
+  50000,
+  200000,
+
+  blocksize_short_44,
+  blocksize_long_44,
+
+  _psy_tone_masteratt_44,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_otherblock,
+  _vp_tonemask_adj_longblock,
+  _vp_tonemask_adj_otherblock,
+
+  _psy_noiseguards_44,
+  _psy_noisebias_impulse,
+  _psy_noisebias_padding,
+  _psy_noisebias_trans,
+  _psy_noisebias_long,
+  _psy_noise_suppress,
+
+  _psy_compand_44,
+  _psy_compand_short_mapping,
+  _psy_compand_long_mapping,
+
+  {_noise_start_short_44,_noise_start_long_44},
+  {_noise_part_short_44,_noise_part_long_44},
+  _noise_thresh_44,
+
+  _psy_ath_floater,
+  _psy_ath_abs,
+
+  _psy_lowpass_44,
+
+  _psy_global_44,
+  _global_mapping_44,
+  _psy_stereo_modes_44,
+
+  _floor_books,
+  _floor,
+  2,
+  _floor_mapping_44,
+
+  _mapres_template_44_stereo
+};
+
+static const ve_setup_data_template ve_setup_X_uncoupled={
+  11,
+  rate_mapping_X,
+  quality_mapping_44,
+  -1,
+  50000,
+  200000,
+
+  blocksize_short_44,
+  blocksize_long_44,
+
+  _psy_tone_masteratt_44,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_otherblock,
+  _vp_tonemask_adj_longblock,
+  _vp_tonemask_adj_otherblock,
+
+  _psy_noiseguards_44,
+  _psy_noisebias_impulse,
+  _psy_noisebias_padding,
+  _psy_noisebias_trans,
+  _psy_noisebias_long,
+  _psy_noise_suppress,
+
+  _psy_compand_44,
+  _psy_compand_short_mapping,
+  _psy_compand_long_mapping,
+
+  {_noise_start_short_44,_noise_start_long_44},
+  {_noise_part_short_44,_noise_part_long_44},
+  _noise_thresh_44,
+
+  _psy_ath_floater,
+  _psy_ath_abs,
+
+  _psy_lowpass_44,
+
+  _psy_global_44,
+  _global_mapping_44,
+  NULL,
+
+  _floor_books,
+  _floor,
+  2,
+  _floor_mapping_44,
+
+  _mapres_template_44_uncoupled
+};
+
+static const ve_setup_data_template ve_setup_XX_stereo={
+  2,
+  rate_mapping_X,
+  quality_mapping_8,
+  2,
+  0,
+  8000,
+
+  blocksize_8,
+  blocksize_8,
+
+  _psy_tone_masteratt_8,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_8,
+  NULL,
+  _vp_tonemask_adj_8,
+
+  _psy_noiseguards_8,
+  _psy_noisebias_8,
+  _psy_noisebias_8,
+  NULL,
+  NULL,
+  _psy_noise_suppress,
+
+  _psy_compand_8,
+  _psy_compand_8_mapping,
+  NULL,
+
+  {_noise_start_8,_noise_start_8},
+  {_noise_part_8,_noise_part_8},
+  _noise_thresh_5only,
+
+  _psy_ath_floater_8,
+  _psy_ath_abs_8,
+
+  _psy_lowpass_8,
+
+  _psy_global_44,
+  _global_mapping_8,
+  _psy_stereo_modes_8,
+
+  _floor_books,
+  _floor,
+  1,
+  _floor_mapping_8,
+
+  _mapres_template_8_stereo
+};
+
+static const ve_setup_data_template ve_setup_XX_uncoupled={
+  2,
+  rate_mapping_X,
+  quality_mapping_8,
+  -1,
+  0,
+  8000,
+
+  blocksize_8,
+  blocksize_8,
+
+  _psy_tone_masteratt_8,
+  _psy_tone_0dB,
+  _psy_tone_suppress,
+
+  _vp_tonemask_adj_8,
+  NULL,
+  _vp_tonemask_adj_8,
+
+  _psy_noiseguards_8,
+  _psy_noisebias_8,
+  _psy_noisebias_8,
+  NULL,
+  NULL,
+  _psy_noise_suppress,
+
+  _psy_compand_8,
+  _psy_compand_8_mapping,
+  NULL,
+
+  {_noise_start_8,_noise_start_8},
+  {_noise_part_8,_noise_part_8},
+  _noise_thresh_5only,
+
+  _psy_ath_floater_8,
+  _psy_ath_abs_8,
+
+  _psy_lowpass_8,
+
+  _psy_global_44,
+  _global_mapping_8,
+  _psy_stereo_modes_8,
+
+  _floor_books,
+  _floor,
+  1,
+  _floor_mapping_8,
+
+  _mapres_template_8_uncoupled
+};

+ 190 - 0
liboggvorbis/src/os.h

@@ -0,0 +1,190 @@
+#ifndef _OS_H
+#define _OS_H
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: #ifdef jail to whip a few platforms into the UNIX ideal.
+ last mod: $Id: os.h 19031 2013-12-03 19:20:50Z tterribe $
+
+ ********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+#include <ogg/os_types.h>
+
+#include "misc.h"
+
+#ifndef _V_IFDEFJAIL_H_
+#  define _V_IFDEFJAIL_H_
+
+#  ifdef __GNUC__
+#    define STIN static __inline__
+#  elif _WIN32
+#    define STIN static __inline
+#  else
+#    define STIN static
+#  endif
+
+#ifdef DJGPP
+#  define rint(x)   (floor((x)+0.5f))
+#endif
+
+#ifndef M_PI
+#  define M_PI (3.1415926536f)
+#endif
+
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+#  include <malloc.h>
+#  define rint(x)   (floor((x)+0.5f))
+#  define NO_FLOAT_MATH_LIB
+#  define FAST_HYPOT(a, b) sqrt((a)*(a) + (b)*(b))
+#endif
+
+#if defined(__SYMBIAN32__) && defined(__WINS__)
+void *_alloca(size_t size);
+#  define alloca _alloca
+#endif
+
+#ifndef FAST_HYPOT
+#  define FAST_HYPOT hypot
+#endif
+
+#endif
+
+#ifdef HAVE_ALLOCA_H
+#  include <alloca.h>
+#endif
+
+#ifdef USE_MEMORY_H
+#  include <memory.h>
+#endif
+
+#ifndef min
+#  define min(x,y)  ((x)>(y)?(y):(x))
+#endif
+
+#ifndef max
+#  define max(x,y)  ((x)<(y)?(y):(x))
+#endif
+
+
+/* Special i386 GCC implementation */
+#if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__)
+#  define VORBIS_FPU_CONTROL
+/* both GCC and MSVC are kinda stupid about rounding/casting to int.
+   Because of encapsulation constraints (GCC can't see inside the asm
+   block and so we end up doing stupid things like a store/load that
+   is collectively a noop), we do it this way */
+
+/* we must set up the fpu before this works!! */
+
+typedef ogg_int16_t vorbis_fpu_control;
+
+static inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
+  ogg_int16_t ret;
+  ogg_int16_t temp;
+  __asm__ __volatile__("fnstcw %0\n\t"
+          "movw %0,%%dx\n\t"
+          "andw $62463,%%dx\n\t"
+          "movw %%dx,%1\n\t"
+          "fldcw %1\n\t":"=m"(ret):"m"(temp): "dx");
+  *fpu=ret;
+}
+
+static inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
+  __asm__ __volatile__("fldcw %0":: "m"(fpu));
+}
+
+/* assumes the FPU is in round mode! */
+static inline int vorbis_ftoi(double f){  /* yes, double!  Otherwise,
+                                             we get extra fst/fld to
+                                             truncate precision */
+  int i;
+  __asm__("fistl %0": "=m"(i) : "t"(f));
+  return(i);
+}
+#endif /* Special i386 GCC implementation */
+
+
+/* MSVC inline assembly. 32 bit only; inline ASM isn't implemented in the
+ * 64 bit compiler */
+#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_WIN32_WCE)
+#  define VORBIS_FPU_CONTROL
+
+typedef ogg_int16_t vorbis_fpu_control;
+
+static __inline int vorbis_ftoi(double f){
+        int i;
+        __asm{
+                fld f
+                fistp i
+        }
+        return i;
+}
+
+static __inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
+  (void)fpu;
+}
+
+static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
+  (void)fpu;
+}
+
+#endif /* Special MSVC 32 bit implementation */
+
+
+/* Optimized code path for x86_64 builds. Uses SSE2 intrinsics. This can be
+   done safely because all x86_64 CPUs supports SSE2. */
+#if (defined(_MSC_VER) && defined(_WIN64)) || (defined(__GNUC__) && defined (__x86_64__))
+#  define VORBIS_FPU_CONTROL
+
+typedef ogg_int16_t vorbis_fpu_control;
+
+#include <emmintrin.h>
+static __inline int vorbis_ftoi(double f){
+        return _mm_cvtsd_si32(_mm_load_sd(&f));
+}
+
+static __inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
+  (void)fpu;
+}
+
+static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
+  (void)fpu;
+}
+
+#endif /* Special MSVC x64 implementation */
+
+
+/* If no special implementation was found for the current compiler / platform,
+   use the default implementation here: */
+#ifndef VORBIS_FPU_CONTROL
+
+typedef int vorbis_fpu_control;
+
+static int vorbis_ftoi(double f){
+        /* Note: MSVC and GCC (at least on some systems) round towards zero, thus,
+           the floor() call is required to ensure correct roudning of
+           negative numbers */
+        return (int)floor(f+.5);
+}
+
+/* We don't have special code for this compiler/arch, so do it the slow way */
+#  define vorbis_fpu_setround(vorbis_fpu_control) {}
+#  define vorbis_fpu_restore(vorbis_fpu_control) {}
+
+#endif /* default implementation */
+
+#endif /* _OS_H */

File diff suppressed because it is too large
+ 1206 - 0
liboggvorbis/src/psy.c


+ 154 - 0
liboggvorbis/src/psy.h

@@ -0,0 +1,154 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: random psychoacoustics (not including preecho)
+ last mod: $Id: psy.h 16946 2010-03-03 16:12:40Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _V_PSY_H_
+#define _V_PSY_H_
+#include "smallft.h"
+
+#include "backends.h"
+#include "envelope.h"
+
+#ifndef EHMER_MAX
+#define EHMER_MAX 56
+#endif
+
+/* psychoacoustic setup ********************************************/
+#define P_BANDS 17      /* 62Hz to 16kHz */
+#define P_LEVELS 8      /* 30dB to 100dB */
+#define P_LEVEL_0 30.    /* 30 dB */
+#define P_NOISECURVES 3
+
+#define NOISE_COMPAND_LEVELS 40
+typedef struct vorbis_info_psy{
+  int   blockflag;
+
+  float ath_adjatt;
+  float ath_maxatt;
+
+  float tone_masteratt[P_NOISECURVES];
+  float tone_centerboost;
+  float tone_decay;
+  float tone_abs_limit;
+  float toneatt[P_BANDS];
+
+  int noisemaskp;
+  float noisemaxsupp;
+  float noisewindowlo;
+  float noisewindowhi;
+  int   noisewindowlomin;
+  int   noisewindowhimin;
+  int   noisewindowfixed;
+  float noiseoff[P_NOISECURVES][P_BANDS];
+  float noisecompand[NOISE_COMPAND_LEVELS];
+
+  float max_curve_dB;
+
+  int normal_p;
+  int normal_start;
+  int normal_partition;
+  double normal_thresh;
+} vorbis_info_psy;
+
+typedef struct{
+  int   eighth_octave_lines;
+
+  /* for block long/short tuning; encode only */
+  float preecho_thresh[VE_BANDS];
+  float postecho_thresh[VE_BANDS];
+  float stretch_penalty;
+  float preecho_minenergy;
+
+  float ampmax_att_per_sec;
+
+  /* channel coupling config */
+  int   coupling_pkHz[PACKETBLOBS];
+  int   coupling_pointlimit[2][PACKETBLOBS];
+  int   coupling_prepointamp[PACKETBLOBS];
+  int   coupling_postpointamp[PACKETBLOBS];
+  int   sliding_lowpass[2][PACKETBLOBS];
+
+} vorbis_info_psy_global;
+
+typedef struct {
+  float ampmax;
+  int   channels;
+
+  vorbis_info_psy_global *gi;
+  int   coupling_pointlimit[2][P_NOISECURVES];
+} vorbis_look_psy_global;
+
+
+typedef struct {
+  int n;
+  struct vorbis_info_psy *vi;
+
+  float ***tonecurves;
+  float **noiseoffset;
+
+  float *ath;
+  long  *octave;             /* in n.ocshift format */
+  long  *bark;
+
+  long  firstoc;
+  long  shiftoc;
+  int   eighth_octave_lines; /* power of two, please */
+  int   total_octave_lines;
+  long  rate; /* cache it */
+
+  float m_val; /* Masking compensation value */
+
+} vorbis_look_psy;
+
+extern void   _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,
+                           vorbis_info_psy_global *gi,int n,long rate);
+extern void   _vp_psy_clear(vorbis_look_psy *p);
+extern void  *_vi_psy_dup(void *source);
+
+extern void   _vi_psy_free(vorbis_info_psy *i);
+extern vorbis_info_psy *_vi_psy_copy(vorbis_info_psy *i);
+
+extern void _vp_noisemask(vorbis_look_psy *p,
+                          float *logmdct,
+                          float *logmask);
+
+extern void _vp_tonemask(vorbis_look_psy *p,
+                         float *logfft,
+                         float *logmask,
+                         float global_specmax,
+                         float local_specmax);
+
+extern void _vp_offset_and_mix(vorbis_look_psy *p,
+                               float *noise,
+                               float *tone,
+                               int offset_select,
+                               float *logmask,
+                               float *mdct,
+                               float *logmdct);
+
+extern float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd);
+
+extern void _vp_couple_quantize_normalize(int blobno,
+                                          vorbis_info_psy_global *g,
+                                          vorbis_look_psy *p,
+                                          vorbis_info_mapping0 *vi,
+                                          float **mdct,
+                                          int   **iwork,
+                                          int    *nonzero,
+                                          int     sliding_lowpass,
+                                          int     ch);
+
+#endif

+ 45 - 0
liboggvorbis/src/registry.c

@@ -0,0 +1,45 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: registry for time, floor, res backends and channel mappings
+ last mod: $Id: registry.c 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+#include "registry.h"
+#include "misc.h"
+/* seems like major overkill now; the backend numbers will grow into
+   the infrastructure soon enough */
+
+extern const vorbis_func_floor     floor0_exportbundle;
+extern const vorbis_func_floor     floor1_exportbundle;
+extern const vorbis_func_residue   residue0_exportbundle;
+extern const vorbis_func_residue   residue1_exportbundle;
+extern const vorbis_func_residue   residue2_exportbundle;
+extern const vorbis_func_mapping   mapping0_exportbundle;
+
+const vorbis_func_floor     *const _floor_P[]={
+  &floor0_exportbundle,
+  &floor1_exportbundle,
+};
+
+const vorbis_func_residue   *const _residue_P[]={
+  &residue0_exportbundle,
+  &residue1_exportbundle,
+  &residue2_exportbundle,
+};
+
+const vorbis_func_mapping   *const _mapping_P[]={
+  &mapping0_exportbundle,
+};

+ 32 - 0
liboggvorbis/src/registry.h

@@ -0,0 +1,32 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: registry for time, floor, res backends and channel mappings
+ last mod: $Id: registry.h 15531 2008-11-24 23:50:06Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _V_REG_H_
+#define _V_REG_H_
+
+#define VI_TRANSFORMB 1
+#define VI_WINDOWB 1
+#define VI_TIMEB 1
+#define VI_FLOORB 2
+#define VI_RESB 3
+#define VI_MAPB 1
+
+extern const vorbis_func_floor     *const _floor_P[];
+extern const vorbis_func_residue   *const _residue_P[];
+extern const vorbis_func_mapping   *const _mapping_P[];
+
+#endif

+ 899 - 0
liboggvorbis/src/res0.c

@@ -0,0 +1,899 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: residue backend 0, 1 and 2 implementation
+ last mod: $Id: res0.c 19031 2013-12-03 19:20:50Z tterribe $
+
+ ********************************************************************/
+
+/* Slow, slow, slow, simpleminded and did I mention it was slow?  The
+   encode/decode loops are coded for clarity and performance is not
+   yet even a nagging little idea lurking in the shadows.  Oh and BTW,
+   it's slow. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+#include "registry.h"
+#include "codebook.h"
+#include "misc.h"
+#include "os.h"
+
+//#define TRAIN_RES 1
+//#define TRAIN_RESAUX 1
+
+#if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
+#include <stdio.h>
+#endif
+
+typedef struct {
+  vorbis_info_residue0 *info;
+
+  int         parts;
+  int         stages;
+  codebook   *fullbooks;
+  codebook   *phrasebook;
+  codebook ***partbooks;
+
+  int         partvals;
+  int       **decodemap;
+
+  long      postbits;
+  long      phrasebits;
+  long      frames;
+
+#if defined(TRAIN_RES) || defined(TRAIN_RESAUX)
+  int        train_seq;
+  long      *training_data[8][64];
+  float      training_max[8][64];
+  float      training_min[8][64];
+  float     tmin;
+  float     tmax;
+  int       submap;
+#endif
+
+} vorbis_look_residue0;
+
+void res0_free_info(vorbis_info_residue *i){
+  vorbis_info_residue0 *info=(vorbis_info_residue0 *)i;
+  if(info){
+    memset(info,0,sizeof(*info));
+    _ogg_free(info);
+  }
+}
+
+void res0_free_look(vorbis_look_residue *i){
+  int j;
+  if(i){
+
+    vorbis_look_residue0 *look=(vorbis_look_residue0 *)i;
+
+#ifdef TRAIN_RES
+    {
+      int j,k,l;
+      for(j=0;j<look->parts;j++){
+        /*fprintf(stderr,"partition %d: ",j);*/
+        for(k=0;k<8;k++)
+          if(look->training_data[k][j]){
+            char buffer[80];
+            FILE *of;
+            codebook *statebook=look->partbooks[j][k];
+
+            /* long and short into the same bucket by current convention */
+            sprintf(buffer,"res_sub%d_part%d_pass%d.vqd",look->submap,j,k);
+            of=fopen(buffer,"a");
+
+            for(l=0;l<statebook->entries;l++)
+              fprintf(of,"%d:%ld\n",l,look->training_data[k][j][l]);
+
+            fclose(of);
+
+            /*fprintf(stderr,"%d(%.2f|%.2f) ",k,
+              look->training_min[k][j],look->training_max[k][j]);*/
+
+            _ogg_free(look->training_data[k][j]);
+            look->training_data[k][j]=NULL;
+          }
+        /*fprintf(stderr,"\n");*/
+      }
+    }
+    fprintf(stderr,"min/max residue: %g::%g\n",look->tmin,look->tmax);
+
+    /*fprintf(stderr,"residue bit usage %f:%f (%f total)\n",
+            (float)look->phrasebits/look->frames,
+            (float)look->postbits/look->frames,
+            (float)(look->postbits+look->phrasebits)/look->frames);*/
+#endif
+
+
+    /*vorbis_info_residue0 *info=look->info;
+
+    fprintf(stderr,
+            "%ld frames encoded in %ld phrasebits and %ld residue bits "
+            "(%g/frame) \n",look->frames,look->phrasebits,
+            look->resbitsflat,
+            (look->phrasebits+look->resbitsflat)/(float)look->frames);
+
+    for(j=0;j<look->parts;j++){
+      long acc=0;
+      fprintf(stderr,"\t[%d] == ",j);
+      for(k=0;k<look->stages;k++)
+        if((info->secondstages[j]>>k)&1){
+          fprintf(stderr,"%ld,",look->resbits[j][k]);
+          acc+=look->resbits[j][k];
+        }
+
+      fprintf(stderr,":: (%ld vals) %1.2fbits/sample\n",look->resvals[j],
+              acc?(float)acc/(look->resvals[j]*info->grouping):0);
+    }
+    fprintf(stderr,"\n");*/
+
+    for(j=0;j<look->parts;j++)
+      if(look->partbooks[j])_ogg_free(look->partbooks[j]);
+    _ogg_free(look->partbooks);
+    for(j=0;j<look->partvals;j++)
+      _ogg_free(look->decodemap[j]);
+    _ogg_free(look->decodemap);
+
+    memset(look,0,sizeof(*look));
+    _ogg_free(look);
+  }
+}
+
+static int ilog(unsigned int v){
+  int ret=0;
+  while(v){
+    ret++;
+    v>>=1;
+  }
+  return(ret);
+}
+
+static int icount(unsigned int v){
+  int ret=0;
+  while(v){
+    ret+=v&1;
+    v>>=1;
+  }
+  return(ret);
+}
+
+
+void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){
+  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
+  int j,acc=0;
+  oggpack_write(opb,info->begin,24);
+  oggpack_write(opb,info->end,24);
+
+  oggpack_write(opb,info->grouping-1,24);  /* residue vectors to group and
+                                             code with a partitioned book */
+  oggpack_write(opb,info->partitions-1,6); /* possible partition choices */
+  oggpack_write(opb,info->groupbook,8);  /* group huffman book */
+
+  /* secondstages is a bitmask; as encoding progresses pass by pass, a
+     bitmask of one indicates this partition class has bits to write
+     this pass */
+  for(j=0;j<info->partitions;j++){
+    if(ilog(info->secondstages[j])>3){
+      /* yes, this is a minor hack due to not thinking ahead */
+      oggpack_write(opb,info->secondstages[j],3);
+      oggpack_write(opb,1,1);
+      oggpack_write(opb,info->secondstages[j]>>3,5);
+    }else
+      oggpack_write(opb,info->secondstages[j],4); /* trailing zero */
+    acc+=icount(info->secondstages[j]);
+  }
+  for(j=0;j<acc;j++)
+    oggpack_write(opb,info->booklist[j],8);
+
+}
+
+/* vorbis_info is for range checking */
+vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){
+  int j,acc=0;
+  vorbis_info_residue0 *info=_ogg_calloc(1,sizeof(*info));
+  codec_setup_info     *ci=vi->codec_setup;
+
+  info->begin=oggpack_read(opb,24);
+  info->end=oggpack_read(opb,24);
+  info->grouping=oggpack_read(opb,24)+1;
+  info->partitions=oggpack_read(opb,6)+1;
+  info->groupbook=oggpack_read(opb,8);
+
+  /* check for premature EOP */
+  if(info->groupbook<0)goto errout;
+
+  for(j=0;j<info->partitions;j++){
+    int cascade=oggpack_read(opb,3);
+    int cflag=oggpack_read(opb,1);
+    if(cflag<0) goto errout;
+    if(cflag){
+      int c=oggpack_read(opb,5);
+      if(c<0) goto errout;
+      cascade|=(c<<3);
+    }
+    info->secondstages[j]=cascade;
+
+    acc+=icount(cascade);
+  }
+  for(j=0;j<acc;j++){
+    int book=oggpack_read(opb,8);
+    if(book<0) goto errout;
+    info->booklist[j]=book;
+  }
+
+  if(info->groupbook>=ci->books)goto errout;
+  for(j=0;j<acc;j++){
+    if(info->booklist[j]>=ci->books)goto errout;
+    if(ci->book_param[info->booklist[j]]->maptype==0)goto errout;
+  }
+
+  /* verify the phrasebook is not specifying an impossible or
+     inconsistent partitioning scheme. */
+  /* modify the phrasebook ranging check from r16327; an early beta
+     encoder had a bug where it used an oversized phrasebook by
+     accident.  These files should continue to be playable, but don't
+     allow an exploit */
+  {
+    int entries = ci->book_param[info->groupbook]->entries;
+    int dim = ci->book_param[info->groupbook]->dim;
+    int partvals = 1;
+    if (dim<1) goto errout;
+    while(dim>0){
+      partvals *= info->partitions;
+      if(partvals > entries) goto errout;
+      dim--;
+    }
+    info->partvals = partvals;
+  }
+
+  return(info);
+ errout:
+  res0_free_info(info);
+  return(NULL);
+}
+
+vorbis_look_residue *res0_look(vorbis_dsp_state *vd,
+                               vorbis_info_residue *vr){
+  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
+  vorbis_look_residue0 *look=_ogg_calloc(1,sizeof(*look));
+  codec_setup_info     *ci=vd->vi->codec_setup;
+
+  int j,k,acc=0;
+  int dim;
+  int maxstage=0;
+  look->info=info;
+
+  look->parts=info->partitions;
+  look->fullbooks=ci->fullbooks;
+  look->phrasebook=ci->fullbooks+info->groupbook;
+  dim=look->phrasebook->dim;
+
+  look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks));
+
+  for(j=0;j<look->parts;j++){
+    int stages=ilog(info->secondstages[j]);
+    if(stages){
+      if(stages>maxstage)maxstage=stages;
+      look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j]));
+      for(k=0;k<stages;k++)
+        if(info->secondstages[j]&(1<<k)){
+          look->partbooks[j][k]=ci->fullbooks+info->booklist[acc++];
+#ifdef TRAIN_RES
+          look->training_data[k][j]=_ogg_calloc(look->partbooks[j][k]->entries,
+                                           sizeof(***look->training_data));
+#endif
+        }
+    }
+  }
+
+  look->partvals=1;
+  for(j=0;j<dim;j++)
+      look->partvals*=look->parts;
+
+  look->stages=maxstage;
+  look->decodemap=_ogg_malloc(look->partvals*sizeof(*look->decodemap));
+  for(j=0;j<look->partvals;j++){
+    long val=j;
+    long mult=look->partvals/look->parts;
+    look->decodemap[j]=_ogg_malloc(dim*sizeof(*look->decodemap[j]));
+    for(k=0;k<dim;k++){
+      long deco=val/mult;
+      val-=deco*mult;
+      mult/=look->parts;
+      look->decodemap[j][k]=deco;
+    }
+  }
+#if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
+  {
+    static int train_seq=0;
+    look->train_seq=train_seq++;
+  }
+#endif
+  return(look);
+}
+
+/* break an abstraction and copy some code for performance purposes */
+static int local_book_besterror(codebook *book,int *a){
+  int dim=book->dim;
+  int i,j,o;
+  int minval=book->minval;
+  int del=book->delta;
+  int qv=book->quantvals;
+  int ze=(qv>>1);
+  int index=0;
+  /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */
+  int p[8]={0,0,0,0,0,0,0,0};
+
+  if(del!=1){
+    for(i=0,o=dim;i<dim;i++){
+      int v = (a[--o]-minval+(del>>1))/del;
+      int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1));
+      index = index*qv+ (m<0?0:(m>=qv?qv-1:m));
+      p[o]=v*del+minval;
+    }
+  }else{
+    for(i=0,o=dim;i<dim;i++){
+      int v = a[--o]-minval;
+      int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1));
+      index = index*qv+ (m<0?0:(m>=qv?qv-1:m));
+      p[o]=v*del+minval;
+    }
+  }
+
+  if(book->c->lengthlist[index]<=0){
+    const static_codebook *c=book->c;
+    int best=-1;
+    /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */
+    int e[8]={0,0,0,0,0,0,0,0};
+    int maxval = book->minval + book->delta*(book->quantvals-1);
+    for(i=0;i<book->entries;i++){
+      if(c->lengthlist[i]>0){
+        int this=0;
+        for(j=0;j<dim;j++){
+          int val=(e[j]-a[j]);
+          this+=val*val;
+        }
+        if(best==-1 || this<best){
+          memcpy(p,e,sizeof(p));
+          best=this;
+          index=i;
+        }
+      }
+      /* assumes the value patterning created by the tools in vq/ */
+      j=0;
+      while(e[j]>=maxval)
+        e[j++]=0;
+      if(e[j]>=0)
+        e[j]+=book->delta;
+      e[j]= -e[j];
+    }
+  }
+
+  if(index>-1){
+    for(i=0;i<dim;i++)
+      *a++ -= p[i];
+  }
+
+  return(index);
+}
+
+#ifdef TRAIN_RES
+static int _encodepart(oggpack_buffer *opb,int *vec, int n,
+                       codebook *book,long *acc){
+#else
+static int _encodepart(oggpack_buffer *opb,int *vec, int n,
+                       codebook *book){
+#endif
+  int i,bits=0;
+  int dim=book->dim;
+  int step=n/dim;
+
+  for(i=0;i<step;i++){
+    int entry=local_book_besterror(book,vec+i*dim);
+
+#ifdef TRAIN_RES
+    if(entry>=0)
+      acc[entry]++;
+#endif
+
+    bits+=vorbis_book_encode(book,entry,opb);
+
+  }
+
+  return(bits);
+}
+
+static long **_01class(vorbis_block *vb,vorbis_look_residue *vl,
+                       int **in,int ch){
+  long i,j,k;
+  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
+  vorbis_info_residue0 *info=look->info;
+
+  /* move all this setup out later */
+  int samples_per_partition=info->grouping;
+  int possible_partitions=info->partitions;
+  int n=info->end-info->begin;
+
+  int partvals=n/samples_per_partition;
+  long **partword=_vorbis_block_alloc(vb,ch*sizeof(*partword));
+  float scale=100./samples_per_partition;
+
+  /* we find the partition type for each partition of each
+     channel.  We'll go back and do the interleaved encoding in a
+     bit.  For now, clarity */
+
+  for(i=0;i<ch;i++){
+    partword[i]=_vorbis_block_alloc(vb,n/samples_per_partition*sizeof(*partword[i]));
+    memset(partword[i],0,n/samples_per_partition*sizeof(*partword[i]));
+  }
+
+  for(i=0;i<partvals;i++){
+    int offset=i*samples_per_partition+info->begin;
+    for(j=0;j<ch;j++){
+      int max=0;
+      int ent=0;
+      for(k=0;k<samples_per_partition;k++){
+        if(abs(in[j][offset+k])>max)max=abs(in[j][offset+k]);
+        ent+=abs(in[j][offset+k]);
+      }
+      ent*=scale;
+
+      for(k=0;k<possible_partitions-1;k++)
+        if(max<=info->classmetric1[k] &&
+           (info->classmetric2[k]<0 || ent<info->classmetric2[k]))
+          break;
+
+      partword[j][i]=k;
+    }
+  }
+
+#ifdef TRAIN_RESAUX
+  {
+    FILE *of;
+    char buffer[80];
+
+    for(i=0;i<ch;i++){
+      sprintf(buffer,"resaux_%d.vqd",look->train_seq);
+      of=fopen(buffer,"a");
+      for(j=0;j<partvals;j++)
+        fprintf(of,"%ld, ",partword[i][j]);
+      fprintf(of,"\n");
+      fclose(of);
+    }
+  }
+#endif
+  look->frames++;
+
+  return(partword);
+}
+
+/* designed for stereo or other modes where the partition size is an
+   integer multiple of the number of channels encoded in the current
+   submap */
+static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,int **in,
+                      int ch){
+  long i,j,k,l;
+  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
+  vorbis_info_residue0 *info=look->info;
+
+  /* move all this setup out later */
+  int samples_per_partition=info->grouping;
+  int possible_partitions=info->partitions;
+  int n=info->end-info->begin;
+
+  int partvals=n/samples_per_partition;
+  long **partword=_vorbis_block_alloc(vb,sizeof(*partword));
+
+#if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
+  FILE *of;
+  char buffer[80];
+#endif
+
+  partword[0]=_vorbis_block_alloc(vb,partvals*sizeof(*partword[0]));
+  memset(partword[0],0,partvals*sizeof(*partword[0]));
+
+  for(i=0,l=info->begin/ch;i<partvals;i++){
+    int magmax=0;
+    int angmax=0;
+    for(j=0;j<samples_per_partition;j+=ch){
+      if(abs(in[0][l])>magmax)magmax=abs(in[0][l]);
+      for(k=1;k<ch;k++)
+        if(abs(in[k][l])>angmax)angmax=abs(in[k][l]);
+      l++;
+    }
+
+    for(j=0;j<possible_partitions-1;j++)
+      if(magmax<=info->classmetric1[j] &&
+         angmax<=info->classmetric2[j])
+        break;
+
+    partword[0][i]=j;
+
+  }
+
+#ifdef TRAIN_RESAUX
+  sprintf(buffer,"resaux_%d.vqd",look->train_seq);
+  of=fopen(buffer,"a");
+  for(i=0;i<partvals;i++)
+    fprintf(of,"%ld, ",partword[0][i]);
+  fprintf(of,"\n");
+  fclose(of);
+#endif
+
+  look->frames++;
+
+  return(partword);
+}
+
+static int _01forward(oggpack_buffer *opb,
+                      vorbis_look_residue *vl,
+                      int **in,int ch,
+                      long **partword,
+#ifdef TRAIN_RES
+                      int (*encode)(oggpack_buffer *,int *,int,
+                                    codebook *,long *),
+                      int submap
+#else
+                      int (*encode)(oggpack_buffer *,int *,int,
+                                    codebook *)
+#endif
+){
+  long i,j,k,s;
+  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
+  vorbis_info_residue0 *info=look->info;
+
+#ifdef TRAIN_RES
+  look->submap=submap;
+#endif
+
+  /* move all this setup out later */
+  int samples_per_partition=info->grouping;
+  int possible_partitions=info->partitions;
+  int partitions_per_word=look->phrasebook->dim;
+  int n=info->end-info->begin;
+
+  int partvals=n/samples_per_partition;
+  long resbits[128];
+  long resvals[128];
+
+#ifdef TRAIN_RES
+  for(i=0;i<ch;i++)
+    for(j=info->begin;j<info->end;j++){
+      if(in[i][j]>look->tmax)look->tmax=in[i][j];
+      if(in[i][j]<look->tmin)look->tmin=in[i][j];
+    }
+#endif
+
+  memset(resbits,0,sizeof(resbits));
+  memset(resvals,0,sizeof(resvals));
+
+  /* we code the partition words for each channel, then the residual
+     words for a partition per channel until we've written all the
+     residual words for that partition word.  Then write the next
+     partition channel words... */
+
+  for(s=0;s<look->stages;s++){
+
+    for(i=0;i<partvals;){
+
+      /* first we encode a partition codeword for each channel */
+      if(s==0){
+        for(j=0;j<ch;j++){
+          long val=partword[j][i];
+          for(k=1;k<partitions_per_word;k++){
+            val*=possible_partitions;
+            if(i+k<partvals)
+              val+=partword[j][i+k];
+          }
+
+          /* training hack */
+          if(val<look->phrasebook->entries)
+            look->phrasebits+=vorbis_book_encode(look->phrasebook,val,opb);
+#if 0 /*def TRAIN_RES*/
+          else
+            fprintf(stderr,"!");
+#endif
+
+        }
+      }
+
+      /* now we encode interleaved residual values for the partitions */
+      for(k=0;k<partitions_per_word && i<partvals;k++,i++){
+        long offset=i*samples_per_partition+info->begin;
+
+        for(j=0;j<ch;j++){
+          if(s==0)resvals[partword[j][i]]+=samples_per_partition;
+          if(info->secondstages[partword[j][i]]&(1<<s)){
+            codebook *statebook=look->partbooks[partword[j][i]][s];
+            if(statebook){
+              int ret;
+#ifdef TRAIN_RES
+              long *accumulator=NULL;
+              accumulator=look->training_data[s][partword[j][i]];
+              {
+                int l;
+                int *samples=in[j]+offset;
+                for(l=0;l<samples_per_partition;l++){
+                  if(samples[l]<look->training_min[s][partword[j][i]])
+                    look->training_min[s][partword[j][i]]=samples[l];
+                  if(samples[l]>look->training_max[s][partword[j][i]])
+                    look->training_max[s][partword[j][i]]=samples[l];
+                }
+              }
+              ret=encode(opb,in[j]+offset,samples_per_partition,
+                         statebook,accumulator);
+#else
+              ret=encode(opb,in[j]+offset,samples_per_partition,
+                         statebook);
+#endif
+
+              look->postbits+=ret;
+              resbits[partword[j][i]]+=ret;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  return(0);
+}
+
+/* a truncated packet here just means 'stop working'; it's not an error */
+static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
+                      float **in,int ch,
+                      long (*decodepart)(codebook *, float *,
+                                         oggpack_buffer *,int)){
+
+  long i,j,k,l,s;
+  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
+  vorbis_info_residue0 *info=look->info;
+
+  /* move all this setup out later */
+  int samples_per_partition=info->grouping;
+  int partitions_per_word=look->phrasebook->dim;
+  int max=vb->pcmend>>1;
+  int end=(info->end<max?info->end:max);
+  int n=end-info->begin;
+
+  if(n>0){
+    int partvals=n/samples_per_partition;
+    int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
+    int ***partword=alloca(ch*sizeof(*partword));
+
+    for(j=0;j<ch;j++)
+      partword[j]=_vorbis_block_alloc(vb,partwords*sizeof(*partword[j]));
+
+    for(s=0;s<look->stages;s++){
+
+      /* each loop decodes on partition codeword containing
+         partitions_per_word partitions */
+      for(i=0,l=0;i<partvals;l++){
+        if(s==0){
+          /* fetch the partition word for each channel */
+          for(j=0;j<ch;j++){
+            int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
+
+            if(temp==-1 || temp>=info->partvals)goto eopbreak;
+            partword[j][l]=look->decodemap[temp];
+            if(partword[j][l]==NULL)goto errout;
+          }
+        }
+
+        /* now we decode residual values for the partitions */
+        for(k=0;k<partitions_per_word && i<partvals;k++,i++)
+          for(j=0;j<ch;j++){
+            long offset=info->begin+i*samples_per_partition;
+            if(info->secondstages[partword[j][l][k]]&(1<<s)){
+              codebook *stagebook=look->partbooks[partword[j][l][k]][s];
+              if(stagebook){
+                if(decodepart(stagebook,in[j]+offset,&vb->opb,
+                              samples_per_partition)==-1)goto eopbreak;
+              }
+            }
+          }
+      }
+    }
+  }
+ errout:
+ eopbreak:
+  return(0);
+}
+
+int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
+                 float **in,int *nonzero,int ch){
+  int i,used=0;
+  for(i=0;i<ch;i++)
+    if(nonzero[i])
+      in[used++]=in[i];
+  if(used)
+    return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add));
+  else
+    return(0);
+}
+
+int res1_forward(oggpack_buffer *opb,vorbis_block *vb,vorbis_look_residue *vl,
+                 int **in,int *nonzero,int ch, long **partword, int submap){
+  int i,used=0;
+  (void)vb;
+  for(i=0;i<ch;i++)
+    if(nonzero[i])
+      in[used++]=in[i];
+
+  if(used){
+#ifdef TRAIN_RES
+    return _01forward(opb,vl,in,used,partword,_encodepart,submap);
+#else
+    (void)submap;
+    return _01forward(opb,vl,in,used,partword,_encodepart);
+#endif
+  }else{
+    return(0);
+  }
+}
+
+long **res1_class(vorbis_block *vb,vorbis_look_residue *vl,
+                  int **in,int *nonzero,int ch){
+  int i,used=0;
+  for(i=0;i<ch;i++)
+    if(nonzero[i])
+      in[used++]=in[i];
+  if(used)
+    return(_01class(vb,vl,in,used));
+  else
+    return(0);
+}
+
+int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,
+                 float **in,int *nonzero,int ch){
+  int i,used=0;
+  for(i=0;i<ch;i++)
+    if(nonzero[i])
+      in[used++]=in[i];
+  if(used)
+    return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add));
+  else
+    return(0);
+}
+
+long **res2_class(vorbis_block *vb,vorbis_look_residue *vl,
+                  int **in,int *nonzero,int ch){
+  int i,used=0;
+  for(i=0;i<ch;i++)
+    if(nonzero[i])used++;
+  if(used)
+    return(_2class(vb,vl,in,ch));
+  else
+    return(0);
+}
+
+/* res2 is slightly more different; all the channels are interleaved
+   into a single vector and encoded. */
+
+int res2_forward(oggpack_buffer *opb,
+                 vorbis_block *vb,vorbis_look_residue *vl,
+                 int **in,int *nonzero,int ch, long **partword,int submap){
+  long i,j,k,n=vb->pcmend/2,used=0;
+
+  /* don't duplicate the code; use a working vector hack for now and
+     reshape ourselves into a single channel res1 */
+  /* ugly; reallocs for each coupling pass :-( */
+  int *work=_vorbis_block_alloc(vb,ch*n*sizeof(*work));
+  for(i=0;i<ch;i++){
+    int *pcm=in[i];
+    if(nonzero[i])used++;
+    for(j=0,k=i;j<n;j++,k+=ch)
+      work[k]=pcm[j];
+  }
+
+  if(used){
+#ifdef TRAIN_RES
+    return _01forward(opb,vl,&work,1,partword,_encodepart,submap);
+#else
+    (void)submap;
+    return _01forward(opb,vl,&work,1,partword,_encodepart);
+#endif
+  }else{
+    return(0);
+  }
+}
+
+/* duplicate code here as speed is somewhat more important */
+int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl,
+                 float **in,int *nonzero,int ch){
+  long i,k,l,s;
+  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
+  vorbis_info_residue0 *info=look->info;
+
+  /* move all this setup out later */
+  int samples_per_partition=info->grouping;
+  int partitions_per_word=look->phrasebook->dim;
+  int max=(vb->pcmend*ch)>>1;
+  int end=(info->end<max?info->end:max);
+  int n=end-info->begin;
+
+  if(n>0){
+    int partvals=n/samples_per_partition;
+    int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
+    int **partword=_vorbis_block_alloc(vb,partwords*sizeof(*partword));
+
+    for(i=0;i<ch;i++)if(nonzero[i])break;
+    if(i==ch)return(0); /* no nonzero vectors */
+
+    for(s=0;s<look->stages;s++){
+      for(i=0,l=0;i<partvals;l++){
+
+        if(s==0){
+          /* fetch the partition word */
+          int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
+          if(temp==-1 || temp>=info->partvals)goto eopbreak;
+          partword[l]=look->decodemap[temp];
+          if(partword[l]==NULL)goto errout;
+        }
+
+        /* now we decode residual values for the partitions */
+        for(k=0;k<partitions_per_word && i<partvals;k++,i++)
+          if(info->secondstages[partword[l][k]]&(1<<s)){
+            codebook *stagebook=look->partbooks[partword[l][k]][s];
+
+            if(stagebook){
+              if(vorbis_book_decodevv_add(stagebook,in,
+                                          i*samples_per_partition+info->begin,ch,
+                                          &vb->opb,samples_per_partition)==-1)
+                goto eopbreak;
+            }
+          }
+      }
+    }
+  }
+ errout:
+ eopbreak:
+  return(0);
+}
+
+
+const vorbis_func_residue residue0_exportbundle={
+  NULL,
+  &res0_unpack,
+  &res0_look,
+  &res0_free_info,
+  &res0_free_look,
+  NULL,
+  NULL,
+  &res0_inverse
+};
+
+const vorbis_func_residue residue1_exportbundle={
+  &res0_pack,
+  &res0_unpack,
+  &res0_look,
+  &res0_free_info,
+  &res0_free_look,
+  &res1_class,
+  &res1_forward,
+  &res1_inverse
+};
+
+const vorbis_func_residue residue2_exportbundle={
+  &res0_pack,
+  &res0_unpack,
+  &res0_look,
+  &res0_free_info,
+  &res0_free_look,
+  &res2_class,
+  &res2_forward,
+  &res2_inverse
+};

+ 90 - 0
liboggvorbis/src/scales.h

@@ -0,0 +1,90 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: linear scale -> dB, Bark and Mel scales
+ last mod: $Id: scales.h 16227 2009-07-08 06:58:46Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _V_SCALES_H_
+#define _V_SCALES_H_
+
+#include <math.h>
+#include "os.h"
+
+#ifdef _MSC_VER
+/* MS Visual Studio doesn't have C99 inline keyword. */
+#define inline __inline
+#endif
+
+/* 20log10(x) */
+#define VORBIS_IEEE_FLOAT32 1
+#ifdef VORBIS_IEEE_FLOAT32
+
+static inline float unitnorm(float x){
+  union {
+    ogg_uint32_t i;
+    float f;
+  } ix;
+  ix.f = x;
+  ix.i = (ix.i & 0x80000000U) | (0x3f800000U);
+  return ix.f;
+}
+
+/* Segher was off (too high) by ~ .3 decibel.  Center the conversion correctly. */
+static inline float todB(const float *x){
+  union {
+    ogg_uint32_t i;
+    float f;
+  } ix;
+  ix.f = *x;
+  ix.i = ix.i&0x7fffffff;
+  return (float)(ix.i * 7.17711438e-7f -764.6161886f);
+}
+
+#define todB_nn(x) todB(x)
+
+#else
+
+static float unitnorm(float x){
+  if(x<0)return(-1.f);
+  return(1.f);
+}
+
+#define todB(x)   (*(x)==0?-400.f:log(*(x)**(x))*4.34294480f)
+#define todB_nn(x)   (*(x)==0.f?-400.f:log(*(x))*8.6858896f)
+
+#endif
+
+#define fromdB(x) (exp((x)*.11512925f))
+
+/* The bark scale equations are approximations, since the original
+   table was somewhat hand rolled.  The below are chosen to have the
+   best possible fit to the rolled tables, thus their somewhat odd
+   appearance (these are more accurate and over a longer range than
+   the oft-quoted bark equations found in the texts I have).  The
+   approximations are valid from 0 - 30kHz (nyquist) or so.
+
+   all f in Hz, z in Bark */
+
+#define toBARK(n)   (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
+#define fromBARK(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f)
+#define toMEL(n)    (log(1.f+(n)*.001f)*1442.695f)
+#define fromMEL(m)  (1000.f*exp((m)/1442.695f)-1000.f)
+
+/* Frequency to octave.  We arbitrarily declare 63.5 Hz to be octave
+   0.0 */
+
+#define toOC(n)     (log(n)*1.442695f-5.965784f)
+#define fromOC(o)   (exp(((o)+5.965784f)*.693147f))
+
+#endif

+ 579 - 0
liboggvorbis/src/sharedbook.c

@@ -0,0 +1,579 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: basic shared codebook operations
+ last mod: $Id: sharedbook.c 19057 2014-01-22 12:32:31Z xiphmont $
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <ogg/ogg.h>
+#include "os.h"
+#include "misc.h"
+#include "vorbis/codec.h"
+#include "codebook.h"
+#include "scales.h"
+
+/**** pack/unpack helpers ******************************************/
+int _ilog(unsigned int v){
+  int ret=0;
+  while(v){
+    ret++;
+    v>>=1;
+  }
+  return(ret);
+}
+
+/* 32 bit float (not IEEE; nonnormalized mantissa +
+   biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm
+   Why not IEEE?  It's just not that important here. */
+
+#define VQ_FEXP 10
+#define VQ_FMAN 21
+#define VQ_FEXP_BIAS 768 /* bias toward values smaller than 1. */
+
+/* doesn't currently guard under/overflow */
+long _float32_pack(float val){
+  int sign=0;
+  long exp;
+  long mant;
+  if(val<0){
+    sign=0x80000000;
+    val= -val;
+  }
+  exp= floor(log(val)/log(2.f)+.001); //+epsilon
+  mant=rint(ldexp(val,(VQ_FMAN-1)-exp));
+  exp=(exp+VQ_FEXP_BIAS)<<VQ_FMAN;
+
+  return(sign|exp|mant);
+}
+
+float _float32_unpack(long val){
+  double mant=val&0x1fffff;
+  int    sign=val&0x80000000;
+  long   exp =(val&0x7fe00000L)>>VQ_FMAN;
+  if(sign)mant= -mant;
+  return(ldexp(mant,exp-(VQ_FMAN-1)-VQ_FEXP_BIAS));
+}
+
+/* given a list of word lengths, generate a list of codewords.  Works
+   for length ordered or unordered, always assigns the lowest valued
+   codewords first.  Extended to handle unused entries (length 0) */
+ogg_uint32_t *_make_words(char *l,long n,long sparsecount){
+  long i,j,count=0;
+  ogg_uint32_t marker[33];
+  ogg_uint32_t *r=_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r));
+  memset(marker,0,sizeof(marker));
+
+  for(i=0;i<n;i++){
+    long length=l[i];
+    if(length>0){
+      ogg_uint32_t entry=marker[length];
+
+      /* when we claim a node for an entry, we also claim the nodes
+         below it (pruning off the imagined tree that may have dangled
+         from it) as well as blocking the use of any nodes directly
+         above for leaves */
+
+      /* update ourself */
+      if(length<32 && (entry>>length)){
+        /* error condition; the lengths must specify an overpopulated tree */
+        _ogg_free(r);
+        return(NULL);
+      }
+      r[count++]=entry;
+
+      /* Look to see if the next shorter marker points to the node
+         above. if so, update it and repeat.  */
+      {
+        for(j=length;j>0;j--){
+
+          if(marker[j]&1){
+            /* have to jump branches */
+            if(j==1)
+              marker[1]++;
+            else
+              marker[j]=marker[j-1]<<1;
+            break; /* invariant says next upper marker would already
+                      have been moved if it was on the same path */
+          }
+          marker[j]++;
+        }
+      }
+
+      /* prune the tree; the implicit invariant says all the longer
+         markers were dangling from our just-taken node.  Dangle them
+         from our *new* node. */
+      for(j=length+1;j<33;j++)
+        if((marker[j]>>1) == entry){
+          entry=marker[j];
+          marker[j]=marker[j-1]<<1;
+        }else
+          break;
+    }else
+      if(sparsecount==0)count++;
+  }
+
+  /* sanity check the huffman tree; an underpopulated tree must be
+     rejected. The only exception is the one-node pseudo-nil tree,
+     which appears to be underpopulated because the tree doesn't
+     really exist; there's only one possible 'codeword' or zero bits,
+     but the above tree-gen code doesn't mark that. */
+  if(sparsecount != 1){
+    for(i=1;i<33;i++)
+      if(marker[i] & (0xffffffffUL>>(32-i))){
+	_ogg_free(r);
+	return(NULL);
+      }
+  }
+
+  /* bitreverse the words because our bitwise packer/unpacker is LSb
+     endian */
+  for(i=0,count=0;i<n;i++){
+    ogg_uint32_t temp=0;
+    for(j=0;j<l[i];j++){
+      temp<<=1;
+      temp|=(r[count]>>j)&1;
+    }
+
+    if(sparsecount){
+      if(l[i])
+        r[count++]=temp;
+    }else
+      r[count++]=temp;
+  }
+
+  return(r);
+}
+
+/* there might be a straightforward one-line way to do the below
+   that's portable and totally safe against roundoff, but I haven't
+   thought of it.  Therefore, we opt on the side of caution */
+long _book_maptype1_quantvals(const static_codebook *b){
+  long vals=floor(pow((float)b->entries,1.f/b->dim));
+
+  /* the above *should* be reliable, but we'll not assume that FP is
+     ever reliable when bitstream sync is at stake; verify via integer
+     means that vals really is the greatest value of dim for which
+     vals^b->bim <= b->entries */
+  /* treat the above as an initial guess */
+  while(1){
+    long acc=1;
+    long acc1=1;
+    int i;
+    for(i=0;i<b->dim;i++){
+      acc*=vals;
+      acc1*=vals+1;
+    }
+    if(acc<=b->entries && acc1>b->entries){
+      return(vals);
+    }else{
+      if(acc>b->entries){
+        vals--;
+      }else{
+        vals++;
+      }
+    }
+  }
+}
+
+/* unpack the quantized list of values for encode/decode ***********/
+/* we need to deal with two map types: in map type 1, the values are
+   generated algorithmically (each column of the vector counts through
+   the values in the quant vector). in map type 2, all the values came
+   in in an explicit list.  Both value lists must be unpacked */
+float *_book_unquantize(const static_codebook *b,int n,int *sparsemap){
+  long j,k,count=0;
+  if(b->maptype==1 || b->maptype==2){
+    int quantvals;
+    float mindel=_float32_unpack(b->q_min);
+    float delta=_float32_unpack(b->q_delta);
+    float *r=_ogg_calloc(n*b->dim,sizeof(*r));
+
+    /* maptype 1 and 2 both use a quantized value vector, but
+       different sizes */
+    switch(b->maptype){
+    case 1:
+      /* most of the time, entries%dimensions == 0, but we need to be
+         well defined.  We define that the possible vales at each
+         scalar is values == entries/dim.  If entries%dim != 0, we'll
+         have 'too few' values (values*dim<entries), which means that
+         we'll have 'left over' entries; left over entries use zeroed
+         values (and are wasted).  So don't generate codebooks like
+         that */
+      quantvals=_book_maptype1_quantvals(b);
+      for(j=0;j<b->entries;j++){
+        if((sparsemap && b->lengthlist[j]) || !sparsemap){
+          float last=0.f;
+          int indexdiv=1;
+          for(k=0;k<b->dim;k++){
+            int index= (j/indexdiv)%quantvals;
+            float val=b->quantlist[index];
+            val=fabs(val)*delta+mindel+last;
+            if(b->q_sequencep)last=val;
+            if(sparsemap)
+              r[sparsemap[count]*b->dim+k]=val;
+            else
+              r[count*b->dim+k]=val;
+            indexdiv*=quantvals;
+          }
+          count++;
+        }
+
+      }
+      break;
+    case 2:
+      for(j=0;j<b->entries;j++){
+        if((sparsemap && b->lengthlist[j]) || !sparsemap){
+          float last=0.f;
+
+          for(k=0;k<b->dim;k++){
+            float val=b->quantlist[j*b->dim+k];
+            val=fabs(val)*delta+mindel+last;
+            if(b->q_sequencep)last=val;
+            if(sparsemap)
+              r[sparsemap[count]*b->dim+k]=val;
+            else
+              r[count*b->dim+k]=val;
+          }
+          count++;
+        }
+      }
+      break;
+    }
+
+    return(r);
+  }
+  return(NULL);
+}
+
+void vorbis_staticbook_destroy(static_codebook *b){
+  if(b->allocedp){
+    if(b->quantlist)_ogg_free(b->quantlist);
+    if(b->lengthlist)_ogg_free(b->lengthlist);
+    memset(b,0,sizeof(*b));
+    _ogg_free(b);
+  } /* otherwise, it is in static memory */
+}
+
+void vorbis_book_clear(codebook *b){
+  /* static book is not cleared; we're likely called on the lookup and
+     the static codebook belongs to the info struct */
+  if(b->valuelist)_ogg_free(b->valuelist);
+  if(b->codelist)_ogg_free(b->codelist);
+
+  if(b->dec_index)_ogg_free(b->dec_index);
+  if(b->dec_codelengths)_ogg_free(b->dec_codelengths);
+  if(b->dec_firsttable)_ogg_free(b->dec_firsttable);
+
+  memset(b,0,sizeof(*b));
+}
+
+int vorbis_book_init_encode(codebook *c,const static_codebook *s){
+
+  memset(c,0,sizeof(*c));
+  c->c=s;
+  c->entries=s->entries;
+  c->used_entries=s->entries;
+  c->dim=s->dim;
+  c->codelist=_make_words(s->lengthlist,s->entries,0);
+  //c->valuelist=_book_unquantize(s,s->entries,NULL);
+  c->quantvals=_book_maptype1_quantvals(s);
+  c->minval=(int)rint(_float32_unpack(s->q_min));
+  c->delta=(int)rint(_float32_unpack(s->q_delta));
+
+  return(0);
+}
+
+static ogg_uint32_t bitreverse(ogg_uint32_t x){
+  x=    ((x>>16)&0x0000ffffUL) | ((x<<16)&0xffff0000UL);
+  x=    ((x>> 8)&0x00ff00ffUL) | ((x<< 8)&0xff00ff00UL);
+  x=    ((x>> 4)&0x0f0f0f0fUL) | ((x<< 4)&0xf0f0f0f0UL);
+  x=    ((x>> 2)&0x33333333UL) | ((x<< 2)&0xccccccccUL);
+  return((x>> 1)&0x55555555UL) | ((x<< 1)&0xaaaaaaaaUL);
+}
+
+static int sort32a(const void *a,const void *b){
+  return ( **(ogg_uint32_t **)a>**(ogg_uint32_t **)b)-
+    ( **(ogg_uint32_t **)a<**(ogg_uint32_t **)b);
+}
+
+/* decode codebook arrangement is more heavily optimized than encode */
+int vorbis_book_init_decode(codebook *c,const static_codebook *s){
+  int i,j,n=0,tabn;
+  int *sortindex;
+  memset(c,0,sizeof(*c));
+
+  /* count actually used entries */
+  for(i=0;i<s->entries;i++)
+    if(s->lengthlist[i]>0)
+      n++;
+
+  c->entries=s->entries;
+  c->used_entries=n;
+  c->dim=s->dim;
+
+  if(n>0){
+
+    /* two different remappings go on here.
+
+    First, we collapse the likely sparse codebook down only to
+    actually represented values/words.  This collapsing needs to be
+    indexed as map-valueless books are used to encode original entry
+    positions as integers.
+
+    Second, we reorder all vectors, including the entry index above,
+    by sorted bitreversed codeword to allow treeless decode. */
+
+    /* perform sort */
+    ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries);
+    ogg_uint32_t **codep=alloca(sizeof(*codep)*n);
+
+    if(codes==NULL)goto err_out;
+
+    for(i=0;i<n;i++){
+      codes[i]=bitreverse(codes[i]);
+      codep[i]=codes+i;
+    }
+
+    qsort(codep,n,sizeof(*codep),sort32a);
+
+    sortindex=alloca(n*sizeof(*sortindex));
+    c->codelist=_ogg_malloc(n*sizeof(*c->codelist));
+    /* the index is a reverse index */
+    for(i=0;i<n;i++){
+      int position=codep[i]-codes;
+      sortindex[position]=i;
+    }
+
+    for(i=0;i<n;i++)
+      c->codelist[sortindex[i]]=codes[i];
+    _ogg_free(codes);
+
+
+    c->valuelist=_book_unquantize(s,n,sortindex);
+    c->dec_index=_ogg_malloc(n*sizeof(*c->dec_index));
+
+    for(n=0,i=0;i<s->entries;i++)
+      if(s->lengthlist[i]>0)
+        c->dec_index[sortindex[n++]]=i;
+
+    c->dec_codelengths=_ogg_malloc(n*sizeof(*c->dec_codelengths));
+    for(n=0,i=0;i<s->entries;i++)
+      if(s->lengthlist[i]>0)
+        c->dec_codelengths[sortindex[n++]]=s->lengthlist[i];
+
+    c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */
+    if(c->dec_firsttablen<5)c->dec_firsttablen=5;
+    if(c->dec_firsttablen>8)c->dec_firsttablen=8;
+
+    tabn=1<<c->dec_firsttablen;
+    c->dec_firsttable=_ogg_calloc(tabn,sizeof(*c->dec_firsttable));
+    c->dec_maxlength=0;
+
+    for(i=0;i<n;i++){
+      if(c->dec_maxlength<c->dec_codelengths[i])
+        c->dec_maxlength=c->dec_codelengths[i];
+      if(c->dec_codelengths[i]<=c->dec_firsttablen){
+        ogg_uint32_t orig=bitreverse(c->codelist[i]);
+        for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++)
+          c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1;
+      }
+    }
+
+    /* now fill in 'unused' entries in the firsttable with hi/lo search
+       hints for the non-direct-hits */
+    {
+      ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen);
+      long lo=0,hi=0;
+
+      for(i=0;i<tabn;i++){
+        ogg_uint32_t word=i<<(32-c->dec_firsttablen);
+        if(c->dec_firsttable[bitreverse(word)]==0){
+          while((lo+1)<n && c->codelist[lo+1]<=word)lo++;
+          while(    hi<n && word>=(c->codelist[hi]&mask))hi++;
+
+          /* we only actually have 15 bits per hint to play with here.
+             In order to overflow gracefully (nothing breaks, efficiency
+             just drops), encode as the difference from the extremes. */
+          {
+            unsigned long loval=lo;
+            unsigned long hival=n-hi;
+
+            if(loval>0x7fff)loval=0x7fff;
+            if(hival>0x7fff)hival=0x7fff;
+            c->dec_firsttable[bitreverse(word)]=
+              0x80000000UL | (loval<<15) | hival;
+          }
+        }
+      }
+    }
+  }
+
+  return(0);
+ err_out:
+  vorbis_book_clear(c);
+  return(-1);
+}
+
+long vorbis_book_codeword(codebook *book,int entry){
+  if(book->c) /* only use with encode; decode optimizations are
+                 allowed to break this */
+    return book->codelist[entry];
+  return -1;
+}
+
+long vorbis_book_codelen(codebook *book,int entry){
+  if(book->c) /* only use with encode; decode optimizations are
+                 allowed to break this */
+    return book->c->lengthlist[entry];
+  return -1;
+}
+
+#ifdef _V_SELFTEST
+
+/* Unit tests of the dequantizer; this stuff will be OK
+   cross-platform, I simply want to be sure that special mapping cases
+   actually work properly; a bug could go unnoticed for a while */
+
+#include <stdio.h>
+
+/* cases:
+
+   no mapping
+   full, explicit mapping
+   algorithmic mapping
+
+   nonsequential
+   sequential
+*/
+
+static long full_quantlist1[]={0,1,2,3,    4,5,6,7, 8,3,6,1};
+static long partial_quantlist1[]={0,7,2};
+
+/* no mapping */
+static_codebook test1={
+  4,16,
+  NULL,
+  0,
+  0,0,0,0,
+  NULL,
+  0
+};
+static float *test1_result=NULL;
+
+/* linear, full mapping, nonsequential */
+static_codebook test2={
+  4,3,
+  NULL,
+  2,
+  -533200896,1611661312,4,0,
+  full_quantlist1,
+  0
+};
+static float test2_result[]={-3,-2,-1,0, 1,2,3,4, 5,0,3,-2};
+
+/* linear, full mapping, sequential */
+static_codebook test3={
+  4,3,
+  NULL,
+  2,
+  -533200896,1611661312,4,1,
+  full_quantlist1,
+  0
+};
+static float test3_result[]={-3,-5,-6,-6, 1,3,6,10, 5,5,8,6};
+
+/* linear, algorithmic mapping, nonsequential */
+static_codebook test4={
+  3,27,
+  NULL,
+  1,
+  -533200896,1611661312,4,0,
+  partial_quantlist1,
+  0
+};
+static float test4_result[]={-3,-3,-3, 4,-3,-3, -1,-3,-3,
+                              -3, 4,-3, 4, 4,-3, -1, 4,-3,
+                              -3,-1,-3, 4,-1,-3, -1,-1,-3,
+                              -3,-3, 4, 4,-3, 4, -1,-3, 4,
+                              -3, 4, 4, 4, 4, 4, -1, 4, 4,
+                              -3,-1, 4, 4,-1, 4, -1,-1, 4,
+                              -3,-3,-1, 4,-3,-1, -1,-3,-1,
+                              -3, 4,-1, 4, 4,-1, -1, 4,-1,
+                              -3,-1,-1, 4,-1,-1, -1,-1,-1};
+
+/* linear, algorithmic mapping, sequential */
+static_codebook test5={
+  3,27,
+  NULL,
+  1,
+  -533200896,1611661312,4,1,
+  partial_quantlist1,
+  0
+};
+static float test5_result[]={-3,-6,-9, 4, 1,-2, -1,-4,-7,
+                              -3, 1,-2, 4, 8, 5, -1, 3, 0,
+                              -3,-4,-7, 4, 3, 0, -1,-2,-5,
+                              -3,-6,-2, 4, 1, 5, -1,-4, 0,
+                              -3, 1, 5, 4, 8,12, -1, 3, 7,
+                              -3,-4, 0, 4, 3, 7, -1,-2, 2,
+                              -3,-6,-7, 4, 1, 0, -1,-4,-5,
+                              -3, 1, 0, 4, 8, 7, -1, 3, 2,
+                              -3,-4,-5, 4, 3, 2, -1,-2,-3};
+
+void run_test(static_codebook *b,float *comp){
+  float *out=_book_unquantize(b,b->entries,NULL);
+  int i;
+
+  if(comp){
+    if(!out){
+      fprintf(stderr,"_book_unquantize incorrectly returned NULL\n");
+      exit(1);
+    }
+
+    for(i=0;i<b->entries*b->dim;i++)
+      if(fabs(out[i]-comp[i])>.0001){
+        fprintf(stderr,"disagreement in unquantized and reference data:\n"
+                "position %d, %g != %g\n",i,out[i],comp[i]);
+        exit(1);
+      }
+
+  }else{
+    if(out){
+      fprintf(stderr,"_book_unquantize returned a value array: \n"
+              " correct result should have been NULL\n");
+      exit(1);
+    }
+  }
+}
+
+int main(){
+  /* run the nine dequant tests, and compare to the hand-rolled results */
+  fprintf(stderr,"Dequant test 1... ");
+  run_test(&test1,test1_result);
+  fprintf(stderr,"OK\nDequant test 2... ");
+  run_test(&test2,test2_result);
+  fprintf(stderr,"OK\nDequant test 3... ");
+  run_test(&test3,test3_result);
+  fprintf(stderr,"OK\nDequant test 4... ");
+  run_test(&test4,test4_result);
+  fprintf(stderr,"OK\nDequant test 5... ");
+  run_test(&test5,test5_result);
+  fprintf(stderr,"OK\n\n");
+
+  return(0);
+}
+
+#endif

File diff suppressed because it is too large
+ 1255 - 0
liboggvorbis/src/smallft.c


+ 34 - 0
liboggvorbis/src/smallft.h

@@ -0,0 +1,34 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: fft transform
+ last mod: $Id: smallft.h 13293 2007-07-24 00:09:47Z xiphmont $
+
+ ********************************************************************/
+
+#ifndef _V_SMFT_H_
+#define _V_SMFT_H_
+
+#include "vorbis/codec.h"
+
+typedef struct {
+  int n;
+  float *trigcache;
+  int *splitcache;
+} drft_lookup;
+
+extern void drft_forward(drft_lookup *l,float *data);
+extern void drft_backward(drft_lookup *l,float *data);
+extern void drft_init(drft_lookup *l,int n);
+extern void drft_clear(drft_lookup *l);
+
+#endif

+ 184 - 0
liboggvorbis/src/synthesis.c

@@ -0,0 +1,184 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: single-block PCM synthesis
+ last mod: $Id: synthesis.c 17474 2010-09-30 03:41:41Z gmaxwell $
+
+ ********************************************************************/
+
+#include <stdio.h>
+#include <ogg/ogg.h>
+#include "vorbis/codec.h"
+#include "codec_internal.h"
+#include "registry.h"
+#include "misc.h"
+#include "os.h"
+
+int vorbis_synthesis(vorbis_block *vb,ogg_packet *op){
+  vorbis_dsp_state     *vd= vb ? vb->vd : 0;
+  private_state        *b= vd ? vd->backend_state : 0;
+  vorbis_info          *vi= vd ? vd->vi : 0;
+  codec_setup_info     *ci= vi ? vi->codec_setup : 0;
+  oggpack_buffer       *opb=vb ? &vb->opb : 0;
+  int                   type,mode,i;
+
+  if (!vd || !b || !vi || !ci || !opb) {
+    return OV_EBADPACKET;
+  }
+
+  /* first things first.  Make sure decode is ready */
+  _vorbis_block_ripcord(vb);
+  oggpack_readinit(opb,op->packet,op->bytes);
+
+  /* Check the packet type */
+  if(oggpack_read(opb,1)!=0){
+    /* Oops.  This is not an audio data packet */
+    return(OV_ENOTAUDIO);
+  }
+
+  /* read our mode and pre/post windowsize */
+  mode=oggpack_read(opb,b->modebits);
+  if(mode==-1){
+    return(OV_EBADPACKET);
+  }
+
+  vb->mode=mode;
+  if(!ci->mode_param[mode]){
+    return(OV_EBADPACKET);
+  }
+
+  vb->W=ci->mode_param[mode]->blockflag;
+  if(vb->W){
+
+    /* this doesn;t get mapped through mode selection as it's used
+       only for window selection */
+    vb->lW=oggpack_read(opb,1);
+    vb->nW=oggpack_read(opb,1);
+    if(vb->nW==-1){
+      return(OV_EBADPACKET);
+    }
+  }else{
+    vb->lW=0;
+    vb->nW=0;
+  }
+
+  /* more setup */
+  vb->granulepos=op->granulepos;
+  vb->sequence=op->packetno;
+  vb->eofflag=op->e_o_s;
+
+  /* alloc pcm passback storage */
+  vb->pcmend=ci->blocksizes[vb->W];
+  vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
+  for(i=0;i<vi->channels;i++)
+    vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
+
+  /* unpack_header enforces range checking */
+  type=ci->map_type[ci->mode_param[mode]->mapping];
+
+  return(_mapping_P[type]->inverse(vb,ci->map_param[ci->mode_param[mode]->
+                                                   mapping]));
+}
+
+/* used to track pcm position without actually performing decode.
+   Useful for sequential 'fast forward' */
+int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op){
+  vorbis_dsp_state     *vd=vb->vd;
+  private_state        *b=vd->backend_state;
+  vorbis_info          *vi=vd->vi;
+  codec_setup_info     *ci=vi->codec_setup;
+  oggpack_buffer       *opb=&vb->opb;
+  int                   mode;
+
+  /* first things first.  Make sure decode is ready */
+  _vorbis_block_ripcord(vb);
+  oggpack_readinit(opb,op->packet,op->bytes);
+
+  /* Check the packet type */
+  if(oggpack_read(opb,1)!=0){
+    /* Oops.  This is not an audio data packet */
+    return(OV_ENOTAUDIO);
+  }
+
+  /* read our mode and pre/post windowsize */
+  mode=oggpack_read(opb,b->modebits);
+  if(mode==-1)return(OV_EBADPACKET);
+
+  vb->mode=mode;
+  if(!ci->mode_param[mode]){
+    return(OV_EBADPACKET);
+  }
+  
+  vb->W=ci->mode_param[mode]->blockflag;
+  if(vb->W){
+    vb->lW=oggpack_read(opb,1);
+    vb->nW=oggpack_read(opb,1);
+    if(vb->nW==-1)   return(OV_EBADPACKET);
+  }else{
+    vb->lW=0;
+    vb->nW=0;
+  }
+
+  /* more setup */
+  vb->granulepos=op->granulepos;
+  vb->sequence=op->packetno;
+  vb->eofflag=op->e_o_s;
+
+  /* no pcm */
+  vb->pcmend=0;
+  vb->pcm=NULL;
+
+  return(0);
+}
+
+long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
+  codec_setup_info     *ci=vi->codec_setup;
+  oggpack_buffer       opb;
+  int                  mode;
+
+  oggpack_readinit(&opb,op->packet,op->bytes);
+
+  /* Check the packet type */
+  if(oggpack_read(&opb,1)!=0){
+    /* Oops.  This is not an audio data packet */
+    return(OV_ENOTAUDIO);
+  }
+
+  {
+    int modebits=0;
+    int v=ci->modes;
+    while(v>1){
+      modebits++;
+      v>>=1;
+    }
+
+    /* read our mode and pre/post windowsize */
+    mode=oggpack_read(&opb,modebits);
+  }
+  if(mode==-1)return(OV_EBADPACKET);
+  return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
+}
+
+int vorbis_synthesis_halfrate(vorbis_info *vi,int flag){
+  /* set / clear half-sample-rate mode */
+  codec_setup_info     *ci=vi->codec_setup;
+
+  /* right now, our MDCT can't handle < 64 sample windows. */
+  if(ci->blocksizes[0]<=64 && flag)return -1;
+  ci->halfrate_flag=(flag?1:0);
+  return 0;
+}
+
+int vorbis_synthesis_halfrate_p(vorbis_info *vi){
+  codec_setup_info     *ci=vi->codec_setup;
+  return ci->halfrate_flag;
+}

File diff suppressed because it is too large
+ 1215 - 0
liboggvorbis/src/vorbisenc.c


File diff suppressed because it is too large
+ 2341 - 0
liboggvorbis/src/vorbisfile.c


File diff suppressed because it is too large
+ 2136 - 0
liboggvorbis/src/window.c


+ 26 - 0
liboggvorbis/src/window.h

@@ -0,0 +1,26 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: window functions
+ last mod: $Id: window.h 19028 2013-12-02 23:23:39Z tterribe $
+
+ ********************************************************************/
+
+#ifndef _V_WINDOW_
+#define _V_WINDOW_
+
+extern const float *_vorbis_window_get(int n);
+extern void _vorbis_apply_window(float *d,int *winno,long *blocksizes,
+                          int lW,int W,int nW);
+
+
+#endif

+ 4 - 2
main.c

@@ -38,6 +38,8 @@
 #define SPRITENUM_SPLASH_CRANE      0x49
 #define NUM_RIX_TITLE               0x05
 
+BOOL g_fUseMidi = FALSE;
+
 static VOID
 PAL_Init(
    WORD             wScreenWidth,
@@ -313,7 +315,7 @@ PAL_SplashScreen(
    if (!SOUND_PlayCDA(7))
    {
       fUseCD = FALSE;
-      PAL_PlayMUS(NUM_RIX_TITLE, TRUE, 2);
+      SOUND_PlayMUS(NUM_RIX_TITLE, TRUE, 2);
    }
 
    //
@@ -482,7 +484,7 @@ PAL_SplashScreen(
 
    if (!fUseCD)
    {
-      PAL_PlayMUS(0, FALSE, 1);
+      SOUND_PlayMUS(0, FALSE, 1);
    }
 
    PAL_FadeOut(1);

+ 1 - 1
main.h

@@ -30,7 +30,7 @@
 #include "map.h"
 #include "res.h"
 #include "scene.h"
-#include "rixplay.h"
+#include "players.h"
 #include "sound.h"
 #include "video.h"
 #include "input.h"

+ 3 - 2
midi.c

@@ -21,7 +21,7 @@
 
 #include "main.h"
 
-#if !defined (CYGWIN) && !defined (DINGOO) &&  !defined (GEKKO) && !defined (GPH)
+#if PAL_HAS_NATIVEMIDI
 
 static INT iMidCurrent = -1;
 static BOOL fMidLoop = FALSE;
@@ -79,7 +79,8 @@ MIDI_Play(
          fMidLoop = fLoop;
       }
    }
-   else
+
+   if (!g_pMid)
    {
       unsigned char   *buf;
       int              size;

+ 157 - 0
mp3player.c

@@ -0,0 +1,157 @@
+/* -*- mode: c++; tab-width: 4; c-basic-offset: 4; c-file-style: "linux" -*- */
+//
+// Copyright (c) 2015, Lou Yihua <louyihua@21cn.com>.
+// All rights reserved.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include "util.h"
+
+#if PAL_HAS_MP3
+
+#include "sound.h"
+#include "players.h"
+#include "libmad/music_mad.h"
+
+typedef struct tagMP3PLAYER
+{
+	MUSICPLAYER_FUNCTIONS;
+
+	mad_data           *pMP3;
+	INT                 iMusic;
+	BOOL                fLoop;
+} MP3PLAYER, *LPMP3PLAYER;
+
+static VOID MP3_Close(
+	LPMP3PLAYER player
+	)
+{
+	if (player->pMP3)
+	{
+		mad_stop(player->pMP3);
+		mad_closeFile(player->pMP3);
+
+		player->pMP3 = NULL;
+	}
+}
+
+static VOID
+MP3_FillBuffer(
+	VOID       *object,
+	LPBYTE      stream,
+	INT         len
+	)
+{
+	LPMP3PLAYER player = (LPMP3PLAYER)object;
+	if (player->pMP3) {
+		mad_getSamples(player->pMP3, stream, len);
+
+		if (!mad_isPlaying(player->pMP3) && player->fLoop)
+		{
+			mad_seek(player->pMP3, 0);
+			mad_start(player->pMP3);
+
+			mad_getSamples(player->pMP3, stream, len);
+		}
+	}
+}
+
+static VOID
+MP3_Shutdown(
+	VOID       *object
+	)
+{
+	if (object)
+	{
+		MP3_Close((LPMP3PLAYER)object);
+		free(object);
+	}
+}
+
+static BOOL
+MP3_Play(
+	VOID       *object,
+	INT         iNum,
+	BOOL        fLoop,
+	FLOAT       flFadeTime
+	)
+{
+	LPMP3PLAYER player = (LPMP3PLAYER)object;
+
+	//
+	// Check for NULL pointer.
+	//
+	if (player == NULL)
+	{
+		return FALSE;
+	}
+
+	player->fLoop = fLoop;
+
+	if (iNum == player->iMusic)
+	{
+		return TRUE;
+	}
+
+	MP3_Close(player);
+
+	if (iNum > 0)
+	{
+		if ((player->pMP3 = mad_openFile(va("%s/mp3/%.2d.mp3", PAL_PREFIX, iNum), SOUND_GetAudioSpec())) == NULL)
+		{
+			player->pMP3 = mad_openFile(va("%s/MP3/%.2d.MP3", PAL_PREFIX, iNum), SOUND_GetAudioSpec());
+		}
+
+		if (player->pMP3)
+		{
+			player->iMusic = iNum;
+			mad_start(player->pMP3);
+			return TRUE;
+		}
+		else
+		{
+			return FALSE;
+		}
+	}
+	else
+	{
+		return TRUE;
+	}
+}
+
+LPMUSICPLAYER
+MP3_Init(
+	LPCSTR szFileName
+	)
+{
+	LPMP3PLAYER player;
+	if (player = (LPMP3PLAYER)malloc(sizeof(MP3PLAYER)))
+	{
+		player->FillBuffer = MP3_FillBuffer;
+		player->Play = MP3_Play;
+		player->Shutdown = MP3_Shutdown;
+
+		player->pMP3 = NULL;
+		player->iMusic = -1;
+		player->fLoop = FALSE;
+		return (LPMUSICPLAYER)player;
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+#endif

+ 531 - 0
oggplay.c

@@ -0,0 +1,531 @@
+/* -*- mode: c++; tab-width: 4; c-basic-offset: 4; c-file-style: "linux" -*- */
+//
+// Copyright (c) 2015, Lou Yihua <louyihua@21cn.com>.
+// All rights reserved.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+// This file is based on the decoder_example.c from libvorbis-1.3.4.
+
+#include "util.h"
+#include "global.h"
+#include "players.h"
+#include "sound.h"
+#include <math.h>
+#if PAL_HAS_OGG
+#include <vorbis\vorbisfile.h>
+
+#define USE_RESAMPLER    1
+
+#if USE_RESAMPLER
+#include "resampler.h"
+#endif
+
+#define FLAG_OY 0x01
+#define FLAG_VI 0x02
+#define FLAG_VC 0x04
+#define FLAG_OS 0x08
+#define FLAG_VD 0x10
+#define FLAG_VB 0x20
+
+#define STAGE_PAGEOUT    1
+#define STAGE_PACKETOUT  2
+#define STAGE_PCMOUT	 3
+#define STAGE_REWIND     4
+
+#define OGG_BUFFER_LENGTH 4096
+
+typedef struct tagOGGPLAYER
+{
+	MUSICPLAYER_FUNCTIONS;
+
+	ogg_sync_state   oy; /* sync and verify incoming physical bitstream */
+	ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */
+	ogg_page         og; /* one Ogg bitstream page. Vorbis packets are inside */
+	vorbis_info      vi; /* struct that stores all the static vorbis bitstream settings */
+	vorbis_comment   vc; /* struct that stores all the bitstream user comments */
+	vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
+	vorbis_block     vb; /* local working space for packet->PCM decode */
+
+	FILE            *fp;
+#if USE_RESAMPLER
+	void            *resampler[2];
+#endif
+	INT              iFlags;
+	INT              iMusic;
+	INT              iStage;
+	BOOL             fLoop;
+	BOOL             fReady;
+} OGGPLAYER, *LPOGGPLAYER;
+
+static SDL_FORCE_INLINE ogg_int16_t OGG_GetSample(float pcm, int volume)
+{
+	int val = floor(pcm * 32767.f + .5f) * volume / SDL_MIX_MAXVOLUME;
+	/* might as well guard against clipping */
+	if (val > 32767) {
+		val = 32767;
+	}
+	else if (val < -32768) {
+		val = -32768;
+	}
+	return SWAP16((ogg_int16_t)val);
+}
+
+#if USE_RESAMPLER
+static SDL_FORCE_INLINE void OGG_FillResample(LPOGGPLAYER player, ogg_int16_t* stream)
+{
+	int i;
+	if (player->vi.channels >= gpGlobals->iAudioChannels) {
+		for (i = 0; i < gpGlobals->iAudioChannels; i++) {
+			stream[i] = resampler_get_and_remove_sample(player->resampler[i]);
+		}
+	}
+	else {
+		ogg_int16_t val = resampler_get_and_remove_sample(player->resampler[0]);
+		for (i = 0; i < gpGlobals->iAudioChannels; i++) {
+			stream[i] = val;
+		}
+	}
+}
+#endif
+
+static void OGG_Cleanup(LPOGGPLAYER player)
+{
+#if USE_RESAMPLER
+	int i;
+	for (i = 0; i < gpGlobals->iAudioChannels; i++) resampler_clear(player->resampler[0]);
+#endif
+	/* Do various cleanups */
+	if (player->iFlags & FLAG_VB) vorbis_block_clear(&player->vb);
+	if (player->iFlags & FLAG_VD) vorbis_dsp_clear(&player->vd);
+	if (player->iFlags & FLAG_OS) ogg_stream_clear(&player->os);
+	if (player->iFlags & FLAG_VC) vorbis_comment_clear(&player->vc);
+	if (player->iFlags & FLAG_VI) vorbis_info_clear(&player->vi);  /* must be called last */
+	if (player->iFlags & FLAG_OY) ogg_sync_clear(&player->oy);
+	player->iFlags = player->iStage = 0;
+	player->fReady = FALSE;
+}
+
+
+static BOOL OGG_Rewind(LPOGGPLAYER player)
+{
+	ogg_packet       op; /* one raw packet of data for decode */
+	char *buffer;
+	int i, bytes;
+
+	OGG_Cleanup(player);
+
+	fseek(player->fp, 0, SEEK_SET);
+
+	ogg_sync_init(&player->oy); player->iFlags = FLAG_OY;
+
+	/* grab some data at the head of the stream. We want the first page
+	(which is guaranteed to be small and only contain the Vorbis
+	stream initial header) We need the first page to get the stream
+	serialno. */
+
+	/* submit a 4k block to libvorbis' Ogg layer */
+	buffer = ogg_sync_buffer(&player->oy, OGG_BUFFER_LENGTH);
+	bytes = fread(buffer, 1, OGG_BUFFER_LENGTH, player->fp);
+	ogg_sync_wrote(&player->oy, bytes);
+
+	/* Get the first page. */
+	if (ogg_sync_pageout(&player->oy, &player->og) != 1) {
+		/* have we simply run out of data?  If so, we're done. */
+		/* error case.  Must not be Vorbis data */
+		OGG_Cleanup(player);
+		return (player->fReady = FALSE);
+	}
+
+	/* Get the serial number and set up the rest of decode. */
+	/* serialno first; use it to set up a logical stream */
+	ogg_stream_init(&player->os, ogg_page_serialno(&player->og));
+	player->iFlags |= FLAG_OS;
+
+	/* extract the initial header from the first page and verify that the
+	Ogg bitstream is in fact Vorbis data */
+
+	/* I handle the initial header first instead of just having the code
+	read all three Vorbis headers at once because reading the initial
+	header is an easy way to identify a Vorbis bitstream and it's
+	useful to see that functionality seperated out. */
+
+	vorbis_info_init(&player->vi); player->iFlags |= FLAG_VI;
+	vorbis_comment_init(&player->vc); player->iFlags |= FLAG_VC;
+	if (ogg_stream_pagein(&player->os, &player->og)<0) {
+		/* error; stream version mismatch perhaps */
+		OGG_Cleanup(player);
+		return (player->fReady = FALSE);
+	}
+
+	if (ogg_stream_packetout(&player->os, &op) != 1) {
+		/* no page? must not be vorbis */
+		OGG_Cleanup(player);
+		return (player->fReady = FALSE);
+	}
+
+	if (vorbis_synthesis_headerin(&player->vi, &player->vc, &op)<0) {
+		/* error case; not a vorbis header */
+		OGG_Cleanup(player);
+		return (player->fReady = FALSE);
+	}
+
+	/* At this point, we're sure we're Vorbis. We've set up the logical
+	(Ogg) bitstream decoder. Get the comment and codebook headers and
+	set up the Vorbis decoder */
+
+	/* The next two packets in order are the comment and codebook headers.
+	They're likely large and may span multiple pages. Thus we read
+	and submit data until we get our two packets, watching that no
+	pages are missing. If a page is missing, error out; losing a
+	header page is the only place where missing data is fatal. */
+
+	i = 0;
+	while (i < 2) {
+		while (i < 2) {
+			int result = ogg_sync_pageout(&player->oy, &player->og);
+			if (result == 0)break; /* Need more data */
+								   /* Don't complain about missing or corrupt data yet. We'll
+								   catch it at the packet output phase */
+			if (result == 1) {
+				ogg_stream_pagein(&player->os, &player->og); /* we can ignore any errors here
+															 as they'll also become apparent
+															 at packetout */
+				while (i < 2) {
+					result = ogg_stream_packetout(&player->os, &op);
+					if (result == 0)break;
+					if (result < 0) {
+						/* Uh oh; data at some point was corrupted or missing!
+						We can't tolerate that in a header.  Die. */
+						OGG_Cleanup(player);
+						return (player->fReady = FALSE);
+					}
+					result = vorbis_synthesis_headerin(&player->vi, &player->vc, &op);
+					if (result < 0) {
+						OGG_Cleanup(player);
+						return (player->fReady = FALSE);
+					}
+					i++;
+				}
+			}
+		}
+		/* no harm in not checking before adding more */
+		buffer = ogg_sync_buffer(&player->oy, OGG_BUFFER_LENGTH);
+		bytes = fread(buffer, 1, OGG_BUFFER_LENGTH, player->fp);
+		if (bytes == 0 && i < 2) {
+			OGG_Cleanup(player);
+			return (player->fReady = FALSE);
+		}
+		ogg_sync_wrote(&player->oy, bytes);
+	}
+
+	if (vorbis_synthesis_init(&player->vd, &player->vi) == 0) { /* central decode state */
+		vorbis_block_init(&player->vd, &player->vb);            /* local state for most of the decode
+																so multiple block decodes can
+																proceed in parallel. We could init
+																multiple vorbis_block structures
+																for vd here */
+		player->iStage = STAGE_PAGEOUT;
+		player->iFlags |= FLAG_VD | FLAG_VB;
+#if USE_RESAMPLER
+		if (player->vi.rate != gpGlobals->iSampleRate) {
+			for (i = 0; i < gpGlobals->iAudioChannels; i++) {
+				resampler_set_rate(player->resampler[i], player->vi.rate / (double)gpGlobals->iSampleRate);
+			}
+		}
+#endif
+		return (player->fReady = TRUE);
+	}
+	else {
+		OGG_Cleanup(player);
+		return (player->fReady = FALSE);
+	}
+}
+
+static VOID
+OGG_FillBuffer(
+	VOID       *object,
+	LPBYTE      stream,
+	INT         len
+	)
+{
+	LPOGGPLAYER player = (LPOGGPLAYER)object;
+#ifdef __SYMBIAN32__
+	int volume = g_iVolume / 2;
+#else
+	int volume = SDL_MIX_MAXVOLUME / 2;
+#endif
+
+	if (player->fReady) {
+		ogg_packet       op; /* one raw packet of data for decode */
+		int total_bytes = 0, stage = player->iStage;
+
+		while (total_bytes < len) {
+			float **pcm;
+			int samples, result;
+
+			switch (stage)
+			{
+			case STAGE_PAGEOUT: /* PAGEOUT stage */
+				result = ogg_sync_pageout(&player->oy, &player->og);
+				if (result > 0) {
+					/* can safely ignore errors at this point */
+					ogg_stream_pagein(&player->os, &player->og);
+					stage = STAGE_PACKETOUT;
+				}
+				else {
+					if (result == 0) { /* need more data */
+						char *buffer = ogg_sync_buffer(&player->oy, OGG_BUFFER_LENGTH);
+						int bytes = fread(buffer, 1, OGG_BUFFER_LENGTH, player->fp);
+						ogg_sync_wrote(&player->oy, bytes);
+						stage = (bytes > 0) ? STAGE_PAGEOUT : STAGE_REWIND;
+					}
+					break;
+				}
+			case STAGE_PACKETOUT:
+				result = ogg_stream_packetout(&player->os, &op);
+				if (result > 0) {
+					/* we have a packet.  Decode it */
+					if (vorbis_synthesis(&player->vb, &op) == 0) { /* test for success! */
+						vorbis_synthesis_blockin(&player->vd, &player->vb);
+					}
+					stage = STAGE_PCMOUT;
+				}
+				else {
+					if (result == 0) { /* need more data */
+						if (ogg_page_eos(&player->og)) {
+							if (player->fLoop) {
+								stage = STAGE_REWIND;
+							}
+							else {
+								OGG_Cleanup(player);
+								UTIL_CloseFile(player->fp);
+								player->fp = NULL;
+								return;
+							}
+						}
+						else {
+							stage = STAGE_PAGEOUT;
+						}
+					}
+					break;
+				}
+			case STAGE_PCMOUT:
+				if ((samples = vorbis_synthesis_pcmout(&player->vd, &pcm)) > 0) {
+					int bout = (len - total_bytes) / gpGlobals->iAudioChannels / sizeof(ogg_int16_t);
+
+					if (bout > samples) bout = samples;
+#if USE_RESAMPLER
+					if (player->vi.rate != gpGlobals->iSampleRate) { /* Samplerate not same, use resampler */
+						int i, j, to_write;
+						
+						while (samples > 0) { /* Fill as many samples into resampler as possible */
+							to_write = resampler_get_free_count(player->resampler[0]);
+							if (to_write >= samples) to_write = samples;
+							samples -= to_write;
+
+							for (i = 0; i < min(player->vi.channels, gpGlobals->iAudioChannels); i++) {
+								float *mono = pcm[i];
+								for (j = 0; j < to_write; j++) {
+									resampler_write_sample(player->resampler[i], OGG_GetSample(mono[j], volume));
+								}
+							}
+
+							/* Fetch resampled samples if available */
+							while (total_bytes < len && resampler_get_sample_count(player->resampler[0])) {
+								OGG_FillResample(player, (ogg_int16_t *)(stream + total_bytes));
+								total_bytes += gpGlobals->iAudioChannels * sizeof(ogg_int16_t);
+							}
+						}
+					}
+					else
+#endif
+					{
+						int i, j;
+
+						if (player->vi.channels >= gpGlobals->iAudioChannels)
+						{
+							/* convert floats to 16 bit signed ints (host order) and interleave */
+							for (i = 0; i < gpGlobals->iAudioChannels; i++) {
+								ogg_int16_t *ptr = (ogg_int16_t *)(stream + total_bytes) + i;
+								float *mono = pcm[i];
+								for (j = 0; j < bout; j++) {
+									*ptr = OGG_GetSample(mono[j], volume);
+									ptr += gpGlobals->iAudioChannels;
+								}
+							}
+						}
+						else
+						{
+							ogg_int16_t *ptr = (ogg_int16_t *)(stream + total_bytes);
+							float *mono = pcm[0];
+							for (j = 0; j < bout; j++) {
+								ogg_int16_t val = OGG_GetSample(mono[j], volume);
+								for (i = 0; i < gpGlobals->iAudioChannels; i++) {
+									*ptr++ = val;
+								}
+							}
+						}
+
+						total_bytes += bout * gpGlobals->iAudioChannels * sizeof(ogg_int16_t);
+					}
+					/* tell libvorbis how many samples we actually consumed */
+					vorbis_synthesis_read(&player->vd, bout);
+				}
+				else {
+					stage = STAGE_PACKETOUT;
+				}
+				break;
+			case STAGE_REWIND:
+#if USE_RESAMPLER
+				if (player->vi.rate != gpGlobals->iSampleRate) { /* If there are samples in the resampler, fetch them first */
+					while (total_bytes < len && resampler_get_sample_count(player->resampler[0])) {
+						OGG_FillResample(player, (ogg_int16_t *)(stream + total_bytes));
+						total_bytes += gpGlobals->iAudioChannels * sizeof(ogg_int16_t);
+					}
+					/* Break out if there are still samples in the resampler */
+					if (resampler_get_sample_count(player->resampler[0])) break;
+				}
+#endif
+				OGG_Rewind(player);
+				stage = player->iStage;
+				break;
+			default:
+				return;
+			}
+		}
+		player->iStage = stage;
+	}
+}
+
+static VOID
+OGG_Shutdown(
+	VOID       *object
+	)
+{
+	if (object)
+	{
+		LPOGGPLAYER player = (LPOGGPLAYER)object;
+#if USE_RESAMPLER
+		int i;
+#endif
+		OGG_Cleanup(player);
+#if USE_RESAMPLER
+		for (i = 0; i < gpGlobals->iAudioChannels; i++)
+			resampler_delete(player->resampler[i]);
+#endif
+		if (player->fp) UTIL_CloseFile(player->fp);
+		free(player);
+	}
+}
+
+static BOOL
+OGG_Play(
+	VOID       *object,
+	INT         iNum,
+	BOOL        fLoop,
+	FLOAT       flFadeTime
+	)
+{
+	char filename[256];
+	LPOGGPLAYER player = (LPOGGPLAYER)object;
+
+	//
+	// Check for NULL pointer.
+	//
+	if (player == NULL)
+	{
+		return FALSE;
+	}
+
+	player->fLoop = fLoop;
+
+	if (iNum == player->iMusic)
+	{
+		return TRUE;
+	}
+
+	player->fReady = FALSE;
+	OGG_Cleanup(player);
+	if (player->fp)
+	{
+		UTIL_CloseFile(player->fp);
+		player->fp = NULL;
+	}
+
+	if (iNum == -1)
+	{
+		return TRUE;
+	}
+
+	player->fp = UTIL_OpenFile(strcpy(filename, va("ogg/%.2d.ogg", iNum)));
+	if (player->fp == NULL)
+	{
+		return FALSE;
+	}
+	else
+	{
+		player->iMusic = iNum;
+	}
+
+	if (!OGG_Rewind(player))
+	{
+		UTIL_CloseFile(player->fp);
+		player->fp = NULL;
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+LPMUSICPLAYER
+OGG_Init(
+	LPCSTR szFileName
+	)
+{
+	LPOGGPLAYER player;
+	if (player = (LPOGGPLAYER)malloc(sizeof(OGGPLAYER)))
+	{
+#if USE_RESAMPLER
+		int i;
+#endif
+		memset(player, 0, sizeof(LPOGGPLAYER));
+
+		player->FillBuffer = OGG_FillBuffer;
+		player->Play = OGG_Play;
+		player->Shutdown = OGG_Shutdown;
+
+		player->fp = NULL;
+		player->iMusic = -1;
+		player->iFlags = 0;
+		player->iStage = 0;
+		player->fLoop = FALSE;
+		player->fReady = FALSE;
+#if USE_RESAMPLER
+		for (i = 0; i < gpGlobals->iAudioChannels; i++)
+		{
+			player->resampler[i] = resampler_create();
+			resampler_set_quality(player->resampler[i], RESAMPLER_QUALITY_MAX);
+		}
+#endif
+		return (LPMUSICPLAYER)player;
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+#endif

+ 1 - 1
play.c

@@ -576,7 +576,7 @@ PAL_StartFrame(
       //
       if (PAL_ConfirmMenu())
       {
-         PAL_PlayMUS(0, FALSE, 2);
+         SOUND_PlayMUS(0, FALSE, 2);
          PAL_FadeOut(2);
          PAL_Shutdown();
          exit(0);

+ 28 - 14
rixplay.h

@@ -30,29 +30,43 @@ extern "C"
 {
 #endif
 
-VOID
-RIX_FillBuffer(
-   LPBYTE     stream,
-   INT        len
-);
+typedef struct tagMUSICPLAYER
+{
+#define MUSICPLAYER_FUNCTIONS \
+	VOID (*Shutdown)(VOID*); \
+	BOOL (*Play)(VOID*, INT, BOOL, FLOAT); \
+	VOID (*FillBuffer)(VOID*, LPBYTE, INT)
+
+	MUSICPLAYER_FUNCTIONS;
+} MUSICPLAYER, *LPMUSICPLAYER;
 
-INT
+/* RIX */
+
+LPMUSICPLAYER
 RIX_Init(
    LPCSTR     szFileName
 );
 
-VOID
-RIX_Shutdown(
-   VOID
+/* OGG */
+#if PAL_HAS_OGG
+
+LPMUSICPLAYER
+OGG_Init(
+	LPCSTR    szFileName
 );
 
-VOID
-RIX_Play(
-   INT       iNumRIX,
-   BOOL      fLoop,
-   FLOAT     flFadeTime
+#endif
+
+/* MP3 */
+#if PAL_HAS_MP3
+
+LPMUSICPLAYER
+MP3_Init(
+	LPCSTR    szFileName
 );
 
+#endif
+
 #ifdef __cplusplus
 }
 #endif

+ 245 - 227
rixplay.cpp

@@ -17,32 +17,19 @@
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 
-#include "rixplay.h"
+#include "global.h"
+#include "players.h"
 #include "sound.h"
 
 #define OPL_SAMPLERATE       49716
 
-#if OPL_SAMPLERATE != PAL_SAMPLE_RATE
-#define USE_RESAMPLER        1
-#endif
-#if PAL_CHANNELS == 2
-#define USE_SURROUNDOPL      1
-#endif
-#define USE_DEMUOPL          1
-
-#if USE_RESAMPLER
 #include "resampler.h"
-#endif
-
 #include "adplug/opl.h"
-#if USE_DEMUOPL
 #include "adplug/demuopl.h"
-#else
+#if PAL_HAS_MAME
 #include "adplug/emuopl.h"
 #endif
-#if USE_SURROUNDOPL
 #include "adplug/surroundopl.h"
-#endif
 #include "adplug/rix.h"
 
 extern "C" BOOL g_fNoMusic;
@@ -50,12 +37,14 @@ extern "C" BOOL g_fNoMusic;
 extern "C" INT  g_iVolume;
 #endif
 
-typedef struct tagRIXPLAYER
+typedef struct tagRIXPLAYER :
+	public MUSICPLAYER
 {
-   tagRIXPLAYER() : iCurrentMusic(-1) {}
    Copl                      *opl;
    CrixPlayer                *rix;
    void                      *resampler[2];
+   BYTE                       buf[(PAL_MAX_SAMPLERATE + 69) / 70 * sizeof(short) * 2];
+   LPBYTE                     pos;
    INT                        iCurrentMusic; // current playing music number
    INT                        iNextMusic; // the next music number to switch to
    DWORD                      dwStartFadeTime;
@@ -63,43 +52,43 @@ typedef struct tagRIXPLAYER
    enum { NONE, FADE_IN, FADE_OUT } FadeType; // fade in or fade out ?
    BOOL                       fLoop;
    BOOL                       fNextLoop;
-   BYTE                       buf[PAL_SAMPLE_RATE / 70 * sizeof(short) * PAL_CHANNELS];
-   LPBYTE                     pos;
+   BOOL                       fReady;
 } RIXPLAYER, *LPRIXPLAYER;
 
-static LPRIXPLAYER gpRixPlayer = NULL;
-
-VOID
+static VOID
 RIX_FillBuffer(
+	VOID      *object,
 	LPBYTE     stream,
 	INT        len
-	)
-	/*++
-	  Purpose:
+)
+/*++
+	Purpose:
 
-		Fill the background music into the sound buffer. Called by the SDL sound
-		callback function only (sound.c: SOUND_FillAudio).
+	Fill the background music into the sound buffer. Called by the SDL sound
+	callback function only (sound.c: SOUND_FillAudio).
 
-	  Parameters:
+	Parameters:
 
-		[OUT] stream - pointer to the stream buffer.
+	[OUT] stream - pointer to the stream buffer.
 
-		[IN]  len - Length of the buffer.
+	[IN]  len - Length of the buffer.
 
-	  Return value:
+	Return value:
 
-		None.
+	None.
 
-	--*/
+--*/
 {
-	INT       i, l, volume = SDL_MIX_MAXVOLUME / 2;
-	UINT      t = SDL_GetTicks();
-
+	INT       i, l;
 #ifdef __SYMBIAN32__
-	volume = g_iVolume / 2;
+	INT       volume = g_iVolume / 2;
+#else
+	INT       volume = SDL_MIX_MAXVOLUME / 2;
 #endif
+	UINT      t = SDL_GetTicks();
+	LPRIXPLAYER pRixPlayer = (LPRIXPLAYER)object;
 
-	if (gpRixPlayer == NULL)
+	if (pRixPlayer == NULL || !pRixPlayer->fReady)
 	{
 		//
 		// Not initialized
@@ -110,50 +99,50 @@ RIX_FillBuffer(
 	//
 	// fading in or fading out
 	//
-	switch (gpRixPlayer->FadeType)
+	switch (pRixPlayer->FadeType)
 	{
 	case RIXPLAYER::FADE_IN:
-		if (t >= gpRixPlayer->dwStartFadeTime + gpRixPlayer->dwFadeLength)
+		if (t >= pRixPlayer->dwStartFadeTime + pRixPlayer->dwFadeLength)
 		{
-			gpRixPlayer->FadeType = RIXPLAYER::NONE;
+			pRixPlayer->FadeType = RIXPLAYER::NONE;
 		}
 		else
 		{
-			volume = (INT)(volume * (t - gpRixPlayer->dwStartFadeTime) / (FLOAT)gpRixPlayer->dwFadeLength);
+			volume = (INT)(volume * (t - pRixPlayer->dwStartFadeTime) / (FLOAT)pRixPlayer->dwFadeLength);
 		}
 		break;
 	case RIXPLAYER::FADE_OUT:
-		if (gpRixPlayer->iCurrentMusic == -1 || t >= gpRixPlayer->dwStartFadeTime + gpRixPlayer->dwFadeLength)
+		if (pRixPlayer->iCurrentMusic == -1 || t >= pRixPlayer->dwStartFadeTime + pRixPlayer->dwFadeLength)
 		{
 			//
 			// There is no current playing music, or fading time has passed.
 			// Start playing the next one.
 			//
-			if (gpRixPlayer->iNextMusic > 0)
+			if (pRixPlayer->iNextMusic > 0)
 			{
-				gpRixPlayer->iCurrentMusic = gpRixPlayer->iNextMusic;
-				gpRixPlayer->fLoop = gpRixPlayer->fNextLoop;
-				gpRixPlayer->FadeType = RIXPLAYER::FADE_IN;
-				gpRixPlayer->dwStartFadeTime = t;
-				gpRixPlayer->opl->init();
-				gpRixPlayer->rix->rewind(gpRixPlayer->iCurrentMusic);
-				if (gpRixPlayer->resampler[0]) resampler_clear(gpRixPlayer->resampler[0]);
-				if (gpRixPlayer->resampler[1]) resampler_clear(gpRixPlayer->resampler[1]);
+				pRixPlayer->iCurrentMusic = pRixPlayer->iNextMusic;
+				pRixPlayer->fLoop = pRixPlayer->fNextLoop;
+				pRixPlayer->FadeType = RIXPLAYER::FADE_IN;
+				pRixPlayer->dwStartFadeTime = t;
+				pRixPlayer->opl->init();
+				pRixPlayer->rix->rewind(pRixPlayer->iCurrentMusic);
+				if (pRixPlayer->resampler[0]) resampler_clear(pRixPlayer->resampler[0]);
+				if (pRixPlayer->resampler[1]) resampler_clear(pRixPlayer->resampler[1]);
 			}
 			else
 			{
-				gpRixPlayer->iCurrentMusic = -1;
-				gpRixPlayer->FadeType = RIXPLAYER::NONE;
+				pRixPlayer->iCurrentMusic = -1;
+				pRixPlayer->FadeType = RIXPLAYER::NONE;
 			}
 			return;
 		}
 		else
 		{
-			volume = (INT)(volume * (1.0f - (t - gpRixPlayer->dwStartFadeTime) / (FLOAT)gpRixPlayer->dwFadeLength));
+			volume = (INT)(volume * (1.0f - (t - pRixPlayer->dwStartFadeTime) / (FLOAT)pRixPlayer->dwFadeLength));
 		}
 		break;
 	default:
-		if (gpRixPlayer->iCurrentMusic <= 0)
+		if (pRixPlayer->iCurrentMusic <= 0)
 		{
 			//
 			// No current playing music
@@ -165,66 +154,68 @@ RIX_FillBuffer(
 	//
 	// Fill the buffer with sound data
 	//
+	int buf_max_len = gpGlobals->iSampleRate / 70 * gpGlobals->iAudioChannels * sizeof(short);
 	while (len > 0)
 	{
-		if (gpRixPlayer->pos == NULL ||
-			gpRixPlayer->pos - gpRixPlayer->buf >= (int)sizeof(gpRixPlayer->buf))
+		if (pRixPlayer->pos == NULL ||
+			pRixPlayer->pos - pRixPlayer->buf >= buf_max_len)
 		{
-			gpRixPlayer->pos = gpRixPlayer->buf;
-			if (!gpRixPlayer->rix->update())
+			pRixPlayer->pos = pRixPlayer->buf;
+			if (!pRixPlayer->rix->update())
 			{
-				if (!gpRixPlayer->fLoop)
+				if (!pRixPlayer->fLoop)
 				{
 					//
 					// Not loop, simply terminate the music
 					//
-					gpRixPlayer->iCurrentMusic = -1;
-					gpRixPlayer->FadeType = RIXPLAYER::NONE;
+					pRixPlayer->iCurrentMusic = -1;
+					pRixPlayer->FadeType = RIXPLAYER::NONE;
 					return;
 				}
-				gpRixPlayer->rix->rewind(gpRixPlayer->iCurrentMusic);
-				if (!gpRixPlayer->rix->update())
+				pRixPlayer->rix->rewind(pRixPlayer->iCurrentMusic);
+				if (!pRixPlayer->rix->update())
 				{
 					//
 					// Something must be wrong
 					//
-					gpRixPlayer->iCurrentMusic = -1;
-					gpRixPlayer->FadeType = RIXPLAYER::NONE;
+					pRixPlayer->iCurrentMusic = -1;
+					pRixPlayer->FadeType = RIXPLAYER::NONE;
 					return;
 				}
 			}
-			int sample_count = PAL_SAMPLE_RATE / 70;
-			if (gpRixPlayer->resampler[0])
+			int sample_count = gpGlobals->iSampleRate / 70;
+			if (pRixPlayer->resampler[0])
 			{
 				unsigned int samples_written = 0;
-				short tempBuf[64 * PAL_CHANNELS]; // hard code on resampler defination
-				short *finalBuf = (short*)gpRixPlayer->buf;
+				short *finalBuf = (short*)pRixPlayer->buf;
 
 				while (sample_count)
 				{
-					int to_write = resampler_get_free_count(gpRixPlayer->resampler[0]);
+					int to_write = resampler_get_free_count(pRixPlayer->resampler[0]);
 					if (to_write)
 					{
-						gpRixPlayer->opl->update(tempBuf, to_write);
+						short *tempBuf = (short*)_alloca(to_write * gpGlobals->iAudioChannels * sizeof(short));
+						pRixPlayer->opl->update(tempBuf, to_write);
 						for (int i = 0; i < to_write; i++)
-						{
-							resampler_write_sample(gpRixPlayer->resampler[0], tempBuf[i * 2]);
-							resampler_write_sample(gpRixPlayer->resampler[1], tempBuf[i * 2 + 1]);
-						}
+							for (int j = 0; j < gpGlobals->iAudioChannels; j++)
+								resampler_write_sample(pRixPlayer->resampler[j], tempBuf[i * gpGlobals->iAudioChannels + j]);
 					}
 
-					finalBuf[samples_written++] = resampler_get_and_remove_sample(gpRixPlayer->resampler[0]);
-					finalBuf[samples_written++] = resampler_get_and_remove_sample(gpRixPlayer->resampler[1]);
-					--sample_count;
+					int to_get = resampler_get_sample_count(pRixPlayer->resampler[0]);
+					if (to_get > sample_count) to_get = sample_count;
+					for (int i = 0; i < to_get; i++)
+						for (int j = 0; j < gpGlobals->iAudioChannels; j++)
+							finalBuf[samples_written++] = resampler_get_and_remove_sample(pRixPlayer->resampler[j]);
+					sample_count -= to_get;
 				}
 			}
 			else
 			{
-				gpRixPlayer->opl->update((short *)(gpRixPlayer->buf), sample_count);
+				pRixPlayer->opl->update((short *)(pRixPlayer->buf), sample_count);
 			}
 		}
 
-		l = sizeof(gpRixPlayer->buf) - (gpRixPlayer->pos - gpRixPlayer->buf);
+		l = buf_max_len - (pRixPlayer->pos - pRixPlayer->buf);
 		if (len < l)
 		{
 			l = len;
@@ -234,187 +225,214 @@ RIX_FillBuffer(
 		// Put audio data into buffer and adjust volume
 		// WARNING: for signed 16-bit little-endian only
 		//
+		SHORT* ptr = (SHORT*)stream;
 		for (i = 0; i < (int)(l / sizeof(SHORT)); i++)
 		{
-			SHORT s = SWAP16((int)(*(SHORT *)(gpRixPlayer->pos)) * volume / SDL_MIX_MAXVOLUME);
-
-			*(SHORT *)(stream) = s;
-			stream += sizeof(SHORT);
-
-			gpRixPlayer->pos += sizeof(SHORT);
+			*ptr++ = SWAP16((int)(*(SHORT *)(pRixPlayer->pos)) * volume / SDL_MIX_MAXVOLUME);
+			pRixPlayer->pos += sizeof(SHORT);
 		}
-
+		stream = (LPBYTE)ptr;
 		len -= l;
 	}
 }
 
-INT
-RIX_Init(
-   LPCSTR     szFileName
+static VOID
+RIX_Shutdown(
+	VOID     *object
 )
 /*++
-  Purpose:
+	Purpose:
 
-    Initialize the RIX player subsystem.
+	Shutdown the RIX player subsystem.
 
-  Parameters:
+	Parameters:
 
-    [IN]  szFileName - Filename of the mus.mkf file.
+	None.
 
-  Return value:
+	Return value:
 
-    0 if success, -1 if cannot allocate memory, -2 if file not found.
+	None.
 
 --*/
 {
-   gpRixPlayer = new RIXPLAYER;
-   if (gpRixPlayer == NULL)
-   {
-      return -1;
-   }
-
-#if USE_DEMUOPL
-   typedef CDemuopl COpl;
-#else
-   typedef CEmuopl  COpl;
-#endif
-
-#if USE_SURROUNDOPL
-   gpRixPlayer->opl = new CSurroundopl(new COpl(OPL_SAMPLERATE, true, false),
-                                       new COpl(OPL_SAMPLERATE, true, false), true);
-#  if USE_RESAMPLER
-   resampler_init();
-   gpRixPlayer->resampler[0] = resampler_create();
-   gpRixPlayer->resampler[1] = resampler_create();
-
-   resampler_set_quality( gpRixPlayer->resampler[0], RESAMPLER_QUALITY_MAX );
-   resampler_set_quality( gpRixPlayer->resampler[1], RESAMPLER_QUALITY_MAX );
-
-   resampler_set_rate( gpRixPlayer->resampler[0], OPL_SAMPLERATE / (double)PAL_SAMPLE_RATE );
-   resampler_set_rate( gpRixPlayer->resampler[1], OPL_SAMPLERATE / (double)PAL_SAMPLE_RATE );
-#  else
-   gpRixPlayer->resampler[0] = NULL;
-   gpRixPlayer->resampler[1] = NULL;
-#  endif
-#else
-   gpRixPlayer->opl = new COpl(OPL_SAMPLERATE, true, PAL_CHANNELS == 2);
-#endif
-
-   if (gpRixPlayer->opl == NULL)
-   {
-      delete gpRixPlayer;
-      return -1;
-   }
-
-   gpRixPlayer->rix = new CrixPlayer(gpRixPlayer->opl);
-   if (gpRixPlayer->rix == NULL)
-   {
-      delete gpRixPlayer->opl;
-      delete gpRixPlayer;
-      return -1;
-   }
-
-   //
-   // Load the MKF file.
-   //
-   if (!gpRixPlayer->rix->load(szFileName, CProvider_Filesystem()))
-   {
-      delete gpRixPlayer->rix;
-      delete gpRixPlayer->opl;
-      delete gpRixPlayer;
-      gpRixPlayer = NULL;
-      return -2;
-   }
-
-   //
-   // Success.
-   //
-   gpRixPlayer->FadeType = RIXPLAYER::NONE;
-   gpRixPlayer->iCurrentMusic = -1;
-   gpRixPlayer->pos = NULL;
-   gpRixPlayer->fLoop = FALSE;
-   gpRixPlayer->fNextLoop = FALSE;
-
-   return 0;
+	if (object != NULL)
+	{
+		LPRIXPLAYER pRixPlayer = (LPRIXPLAYER)object;
+		pRixPlayer->fReady = FALSE;
+		for (int i = 0; i < gpGlobals->iAudioChannels; i++)
+			if (pRixPlayer->resampler[i])
+				resampler_delete(pRixPlayer->resampler[i]);
+		delete pRixPlayer->rix;
+		delete pRixPlayer->opl;
+		delete pRixPlayer;
+	}
 }
 
-VOID
-RIX_Shutdown(
-   VOID
+static BOOL
+RIX_Play(
+	VOID     *object,
+	INT       iNumRIX,
+	BOOL      fLoop,
+	FLOAT     flFadeTime
 )
 /*++
-  Purpose:
+	Purpose:
 
-    Shutdown the RIX player subsystem.
+	Start playing the specified music.
 
-  Parameters:
+	Parameters:
 
-    None.
+	[IN]  iNumRIX - number of the music. 0 to stop playing current music.
 
-  Return value:
+	[IN]  fLoop - Whether the music should be looped or not.
 
-    None.
+	[IN]  flFadeTime - the fade in/out time when switching music.
+
+	Return value:
+
+	None.
 
 --*/
 {
-   if (gpRixPlayer != NULL)
-   {
-      delete gpRixPlayer->rix;
-      delete gpRixPlayer->opl;
-      delete gpRixPlayer;
-
-      gpRixPlayer = NULL;
-   }
-}
+	LPRIXPLAYER pRixPlayer = (LPRIXPLAYER)object;
 
-VOID
-RIX_Play(
-   INT       iNumRIX,
-   BOOL      fLoop,
-   FLOAT     flFadeTime
-)
-/*++
-  Purpose:
+	//
+	// Check for NULL pointer.
+	//
+	if (pRixPlayer == NULL)
+	{
+		return FALSE;
+	}
 
-    Start playing the specified music.
+	//
+	// Stop the current CD music.
+	//
+	SOUND_PlayCDA(-1);
+
+	pRixPlayer->fNextLoop = fLoop;
+
+	if (iNumRIX == pRixPlayer->iCurrentMusic)
+	{
+		return TRUE;
+	}
+
+	pRixPlayer->iNextMusic = iNumRIX;
+	pRixPlayer->dwStartFadeTime = SDL_GetTicks();
+	pRixPlayer->dwFadeLength = (DWORD)(flFadeTime * 1000) / 2;
+	pRixPlayer->FadeType = RIXPLAYER::FADE_OUT;
+	pRixPlayer->fReady = TRUE;
 
-  Parameters:
+	return TRUE;
+}
+
+LPMUSICPLAYER
+RIX_Init(
+	LPCSTR     szFileName
+	)
+	/*++
+	Purpose:
 
-    [IN]  iNumRIX - number of the music. 0 to stop playing current music.
+	Initialize the RIX player subsystem.
 
-    [IN]  fLoop - Whether the music should be looped or not.
+	Parameters:
 
-    [IN]  flFadeTime - the fade in/out time when switching music.
+	[IN]  szFileName - Filename of the mus.mkf file.
 
-  Return value:
+	Return value:
 
-    None.
+	0 if success, -1 if cannot allocate memory, -2 if file not found.
 
---*/
+	--*/
 {
-   //
-   // Check for NULL pointer.
-   //
-   if (gpRixPlayer == NULL)
-   {
-      return;
-   }
-
-   //
-   // Stop the current CD music.
-   //
-   SOUND_PlayCDA(-1);
-    
-   DWORD t = SDL_GetTicks();
-   gpRixPlayer->fNextLoop = fLoop;
-
-   if (iNumRIX == gpRixPlayer->iCurrentMusic && !g_fNoMusic)
-   {
-      return;
-   }
-
-   gpRixPlayer->iNextMusic = iNumRIX;
-   gpRixPlayer->dwStartFadeTime = t;
-   gpRixPlayer->dwFadeLength = (DWORD)(flFadeTime * 1000) / 2;
-   gpRixPlayer->FadeType = RIXPLAYER::FADE_OUT;
+	LPRIXPLAYER pRixPlayer = new RIXPLAYER;
+	if (pRixPlayer == NULL)
+	{
+		return NULL;
+	}
+	else
+	{
+		memset(pRixPlayer, 0, sizeof(RIXPLAYER));
+		pRixPlayer->FillBuffer = RIX_FillBuffer;
+		pRixPlayer->Shutdown = RIX_Shutdown;
+		pRixPlayer->Play = RIX_Play;
+	}
+
+	if (gpGlobals->fUseSurroundOPL)
+	{
+		switch (gpGlobals->eOPLType)
+		{
+		case OPL_DOSBOX:
+			pRixPlayer->opl = new CSurroundopl(
+				new CDemuopl(OPL_SAMPLERATE, true, false),
+				new CDemuopl(OPL_SAMPLERATE, true, false),
+				true);
+			break;
+		case OPL_MAME:
+			pRixPlayer->opl = new CSurroundopl(
+				new CEmuopl(OPL_SAMPLERATE, true, false),
+				new CEmuopl(OPL_SAMPLERATE, true, false),
+				true);
+			break;
+		}
+	}
+	else
+	{
+		switch (gpGlobals->eOPLType)
+		{
+		case OPL_DOSBOX:
+			pRixPlayer->opl = new CDemuopl(OPL_SAMPLERATE, true, gpGlobals->iAudioChannels == 2);
+			break;
+		case OPL_MAME:
+			pRixPlayer->opl = new CEmuopl(OPL_SAMPLERATE, true, gpGlobals->iAudioChannels == 2);
+			break;
+		}
+	}
+
+	if (pRixPlayer->opl == NULL)
+	{
+		delete pRixPlayer;
+		return NULL;
+	}
+
+	pRixPlayer->rix = new CrixPlayer(pRixPlayer->opl);
+	if (pRixPlayer->rix == NULL)
+	{
+		delete pRixPlayer->opl;
+		delete pRixPlayer;
+		return NULL;
+	}
+
+	//
+	// Load the MKF file.
+	//
+	if (!pRixPlayer->rix->load(szFileName, CProvider_Filesystem()))
+	{
+		delete pRixPlayer->rix;
+		delete pRixPlayer->opl;
+		delete pRixPlayer;
+		pRixPlayer = NULL;
+		return NULL;
+	}
+
+	if (OPL_SAMPLERATE != gpGlobals->iSampleRate)
+	{
+		for (int i = 0; i < gpGlobals->iAudioChannels; i++)
+		{
+			pRixPlayer->resampler[i] = resampler_create();
+			resampler_set_quality(pRixPlayer->resampler[i], RESAMPLER_QUALITY_MAX);
+			resampler_set_rate(pRixPlayer->resampler[i], OPL_SAMPLERATE / (double)gpGlobals->iSampleRate);
+		}
+	}
+
+	//
+	// Success.
+	//
+	pRixPlayer->FadeType = RIXPLAYER::NONE;
+	pRixPlayer->iCurrentMusic = -1;
+	pRixPlayer->pos = NULL;
+	pRixPlayer->fLoop = FALSE;
+	pRixPlayer->fNextLoop = FALSE;
+	pRixPlayer->fReady = FALSE;
+
+	return pRixPlayer;
 }

+ 3 - 3
script.c

@@ -1591,7 +1591,7 @@ PAL_InterpretInstruction(
       // Set background music
       //
       gpGlobals->wNumMusic = pScript->rgwOperand[0];
-      PAL_PlayMUS(pScript->rgwOperand[0], (pScript->rgwOperand[0] != 0x3D), pScript->rgwOperand[1]);
+      SOUND_PlayMUS(pScript->rgwOperand[0], (pScript->rgwOperand[0] != 0x3D), pScript->rgwOperand[1]);
       break;
 
    case 0x0044:
@@ -2166,7 +2166,7 @@ PAL_InterpretInstruction(
       //
       // Stop current playing music
       //
-      PAL_PlayMUS(0, FALSE,
+      SOUND_PlayMUS(0, FALSE,
          (pScript->rgwOperand[0] == 0) ? 2.0f : (FLOAT)(pScript->rgwOperand[0]) * 2);
       gpGlobals->wNumMusic = 0;
       break;
@@ -2952,7 +2952,7 @@ PAL_InterpretInstruction(
       //
       if (!SOUND_PlayCDA(pScript->rgwOperand[0]))
       {
-         PAL_PlayMUS(pScript->rgwOperand[1], TRUE, 0);
+         SOUND_PlayMUS(pScript->rgwOperand[1], TRUE, 0);
       }
       break;
 

+ 34 - 0
sdlpal.cfg.example

@@ -29,3 +29,37 @@
 #                   zero for using SDLPAL's internal fonts.
 # Note that this value is ignored when the DOS option is zero.
 #UseEmbeddedFonts=1
+
+# CD: Indicates which type of CD audio source to use. Valid types include 'RAW',
+#     'OGG' and 'MP3'. 'RAW' means use the SDL 1.2's CDAudio API (default when
+#     compiled with SDL 1.2), 'OGG' means use files named as '100xx.ogg' inside
+#     the 'ogg' directory (default when compiled with SDL 2.0), while 'MP3'
+#     means use files named as '100xx.mp3' inside the 'mp3' directory.
+#CD=OGG
+
+# MUSIC: Indicates which type of music source to use. Valid types include 
+#        'RIX', 'MIDI', 'OGG' and 'MP3'. 'RIX' means use the RIX music (default),
+#        'MIDI' means midi (either in 'mus.mkf' or inside 'musics' directory),
+#        'OGG' means use files named as 'xx.ogg' inside the 'ogg' directory, while
+#        'MP3' means use files named as 'xx.mp3' inside the 'mp3' directory.
+#MUSIC=RIX
+
+# OPL: Indicates which type of opl emulator to use. Valid types include 'DOSBOX'
+#      (default) and 'MAME'.  'DOSBOX' means use the opl emulator from dosbox
+#      project, while 'MAME' means use the opl emulator from M.A.M.E project (due
+#      to license issues, this option currently is only for testing purpose and can
+#      only be enabled when complied with a special macro definition.)
+#OPL=DOSBOX
+
+# Stereo: Indicates whether to use mono audio or stereo audio. Non-zero means to use
+#         stereo audio (default), while zero means only use mono audio.
+#Stereo=1
+
+# UseSurroundOPL: Indicates whether to use surround opl emulator or not. Non-zero
+#                 means to using (default), while zero means not to use. Only
+#                 valid when Stereo is set to non-zero.
+#UseSurroundOPL=1
+
+# SampleRate: Indicates which sample rate to use, valid values include 44100 (default),
+#             22050, and some other rates.
+#SampleRate=44100

+ 76 - 3
sdlpal.vcxproj

@@ -54,7 +54,7 @@
     </Midl>
     <ClCompile>
       <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
-      <AdditionalIncludeDirectories>..\SDL2-2.0.3\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\SDL2-2.0.3\include;.\liboggvorbis\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <StringPooling>true</StringPooling>
       <FunctionLevelLinking>true</FunctionLevelLinking>
@@ -91,7 +91,7 @@
     </Midl>
     <ClCompile>
       <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>..\SDL2-2.0.3\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\SDL2-2.0.3\include;.\liboggvorbis\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <MinimalRebuild>true</MinimalRebuild>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -174,6 +174,30 @@
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
+    <ClCompile Include="liboggvorbis\src\analysis.c" />
+    <ClCompile Include="liboggvorbis\src\bitrate.c" />
+    <ClCompile Include="liboggvorbis\src\bitwise.c" />
+    <ClCompile Include="liboggvorbis\src\block.c" />
+    <ClCompile Include="liboggvorbis\src\codebook.c" />
+    <ClCompile Include="liboggvorbis\src\envelope.c" />
+    <ClCompile Include="liboggvorbis\src\floor0.c" />
+    <ClCompile Include="liboggvorbis\src\floor1.c" />
+    <ClCompile Include="liboggvorbis\src\framing.c" />
+    <ClCompile Include="liboggvorbis\src\info.c" />
+    <ClCompile Include="liboggvorbis\src\lookup.c" />
+    <ClCompile Include="liboggvorbis\src\lpc.c" />
+    <ClCompile Include="liboggvorbis\src\lsp.c" />
+    <ClCompile Include="liboggvorbis\src\mapping0.c" />
+    <ClCompile Include="liboggvorbis\src\mdct.c" />
+    <ClCompile Include="liboggvorbis\src\psy.c" />
+    <ClCompile Include="liboggvorbis\src\registry.c" />
+    <ClCompile Include="liboggvorbis\src\res0.c" />
+    <ClCompile Include="liboggvorbis\src\sharedbook.c" />
+    <ClCompile Include="liboggvorbis\src\smallft.c" />
+    <ClCompile Include="liboggvorbis\src\synthesis.c" />
+    <ClCompile Include="liboggvorbis\src\vorbisenc.c" />
+    <ClCompile Include="liboggvorbis\src\vorbisfile.c" />
+    <ClCompile Include="liboggvorbis\src\window.c" />
     <ClCompile Include="magicmenu.c">
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -198,6 +222,8 @@
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
+    <ClCompile Include="mp3player.c" />
+    <ClCompile Include="oggplay.c" />
     <ClCompile Include="palcommon.c">
       <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -444,6 +470,53 @@
     <ClInclude Include="global.h" />
     <ClInclude Include="input.h" />
     <ClInclude Include="itemmenu.h" />
+    <ClInclude Include="liboggvorbis\include\ogg\ogg.h" />
+    <ClInclude Include="liboggvorbis\include\ogg\os_types.h" />
+    <ClInclude Include="liboggvorbis\include\vorbis\codec.h" />
+    <ClInclude Include="liboggvorbis\include\vorbis\vorbisenc.h" />
+    <ClInclude Include="liboggvorbis\include\vorbis\vorbisfile.h" />
+    <ClInclude Include="liboggvorbis\src\backends.h" />
+    <ClInclude Include="liboggvorbis\src\bitrate.h" />
+    <ClInclude Include="liboggvorbis\src\books\coupled\res_books_51.h" />
+    <ClInclude Include="liboggvorbis\src\books\coupled\res_books_stereo.h" />
+    <ClInclude Include="liboggvorbis\src\books\floor\floor_books.h" />
+    <ClInclude Include="liboggvorbis\src\books\uncoupled\res_books_uncoupled.h" />
+    <ClInclude Include="liboggvorbis\src\codebook.h" />
+    <ClInclude Include="liboggvorbis\src\codec_internal.h" />
+    <ClInclude Include="liboggvorbis\src\envelope.h" />
+    <ClInclude Include="liboggvorbis\src\highlevel.h" />
+    <ClInclude Include="liboggvorbis\src\lookup.h" />
+    <ClInclude Include="liboggvorbis\src\lookup_data.h" />
+    <ClInclude Include="liboggvorbis\src\lpc.h" />
+    <ClInclude Include="liboggvorbis\src\lsp.h" />
+    <ClInclude Include="liboggvorbis\src\masking.h" />
+    <ClInclude Include="liboggvorbis\src\mdct.h" />
+    <ClInclude Include="liboggvorbis\src\misc.h" />
+    <ClInclude Include="liboggvorbis\src\modes\floor_all.h" />
+    <ClInclude Include="liboggvorbis\src\modes\psych_11.h" />
+    <ClInclude Include="liboggvorbis\src\modes\psych_16.h" />
+    <ClInclude Include="liboggvorbis\src\modes\psych_44.h" />
+    <ClInclude Include="liboggvorbis\src\modes\psych_8.h" />
+    <ClInclude Include="liboggvorbis\src\modes\residue_16.h" />
+    <ClInclude Include="liboggvorbis\src\modes\residue_44.h" />
+    <ClInclude Include="liboggvorbis\src\modes\residue_44p51.h" />
+    <ClInclude Include="liboggvorbis\src\modes\residue_44u.h" />
+    <ClInclude Include="liboggvorbis\src\modes\residue_8.h" />
+    <ClInclude Include="liboggvorbis\src\modes\setup_11.h" />
+    <ClInclude Include="liboggvorbis\src\modes\setup_16.h" />
+    <ClInclude Include="liboggvorbis\src\modes\setup_22.h" />
+    <ClInclude Include="liboggvorbis\src\modes\setup_32.h" />
+    <ClInclude Include="liboggvorbis\src\modes\setup_44.h" />
+    <ClInclude Include="liboggvorbis\src\modes\setup_44p51.h" />
+    <ClInclude Include="liboggvorbis\src\modes\setup_44u.h" />
+    <ClInclude Include="liboggvorbis\src\modes\setup_8.h" />
+    <ClInclude Include="liboggvorbis\src\modes\setup_X.h" />
+    <ClInclude Include="liboggvorbis\src\os.h" />
+    <ClInclude Include="liboggvorbis\src\psy.h" />
+    <ClInclude Include="liboggvorbis\src\registry.h" />
+    <ClInclude Include="liboggvorbis\src\scales.h" />
+    <ClInclude Include="liboggvorbis\src\smallft.h" />
+    <ClInclude Include="liboggvorbis\src\window.h" />
     <ClInclude Include="magicmenu.h" />
     <ClInclude Include="main.h" />
     <ClInclude Include="map.h" />
@@ -453,7 +526,7 @@
     <ClInclude Include="play.h" />
     <ClInclude Include="res.h" />
     <ClInclude Include="resampler.h" />
-    <ClInclude Include="rixplay.h" />
+    <ClInclude Include="players.h" />
     <ClInclude Include="rngplay.h" />
     <ClInclude Include="scene.h" />
     <ClInclude Include="script.h" />

+ 252 - 3
sdlpal.vcxproj.filters

@@ -21,6 +21,36 @@
     <Filter Include="libmad">
       <UniqueIdentifier>{1e3bd586-dfa2-4acb-8f38-8497f4539508}</UniqueIdentifier>
     </Filter>
+    <Filter Include="liboggvorbis">
+      <UniqueIdentifier>{41409523-ae4d-4412-8d91-8fb39f6d8121}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="liboggvorbis\src">
+      <UniqueIdentifier>{57265997-2f74-4813-ab40-18931967e914}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="liboggvorbis\src\modes">
+      <UniqueIdentifier>{389e57bc-2e50-49da-8358-81f59b8c067b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="liboggvorbis\src\books">
+      <UniqueIdentifier>{16724879-654d-4118-b03c-ec26d3e25011}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="liboggvorbis\src\books\coupled">
+      <UniqueIdentifier>{e24ad128-dd33-48d9-af61-1baeb222252e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="liboggvorbis\src\books\floor">
+      <UniqueIdentifier>{2ecd2b9f-7f2c-4ab7-82af-ff35d0dd195a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="liboggvorbis\src\books\uncoupled">
+      <UniqueIdentifier>{8e0d5701-eaeb-472a-b680-7f82b722f6f9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="liboggvorbis\include">
+      <UniqueIdentifier>{fd63ae43-f47a-450a-a5a9-e7c9d462d157}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="liboggvorbis\include\ogg">
+      <UniqueIdentifier>{e3c854bc-f6de-4b0c-82c3-1f0b05c1520e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="liboggvorbis\include\vorbis">
+      <UniqueIdentifier>{1da4fd33-6d94-4dbe-b0cd-2a9c9041df62}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="battle.c">
@@ -185,6 +215,84 @@
     <ClCompile Include="yj1.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="liboggvorbis\src\analysis.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\bitrate.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\bitwise.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\block.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\codebook.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\envelope.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\floor0.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\floor1.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\framing.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\info.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\lookup.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\lpc.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\lsp.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\mapping0.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\mdct.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\psy.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\registry.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\res0.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\sharedbook.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\smallft.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\synthesis.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\vorbisenc.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\vorbisfile.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="liboggvorbis\src\window.c">
+      <Filter>liboggvorbis\src</Filter>
+    </ClCompile>
+    <ClCompile Include="oggplay.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="mp3player.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="ascii.h">
@@ -244,9 +352,6 @@
     <ClInclude Include="res.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="rixplay.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="rngplay.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -373,6 +478,150 @@
     <ClInclude Include="adplug\kemuopl.h">
       <Filter>adplug</Filter>
     </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\floor_all.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\psych_8.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\psych_11.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\psych_16.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\psych_44.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\residue_8.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\residue_16.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\residue_44.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\residue_44p51.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\residue_44u.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\setup_8.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\setup_11.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\setup_16.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\setup_22.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\setup_32.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\setup_44.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\setup_44p51.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\setup_44u.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\modes\setup_X.h">
+      <Filter>liboggvorbis\src\modes</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\books\coupled\res_books_51.h">
+      <Filter>liboggvorbis\src\books\coupled</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\books\coupled\res_books_stereo.h">
+      <Filter>liboggvorbis\src\books\coupled</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\books\floor\floor_books.h">
+      <Filter>liboggvorbis\src\books\floor</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\books\uncoupled\res_books_uncoupled.h">
+      <Filter>liboggvorbis\src\books\uncoupled</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\backends.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\bitrate.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\codebook.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\codec_internal.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\envelope.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\highlevel.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\lookup.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\lookup_data.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\lpc.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\lsp.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\masking.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\mdct.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\misc.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\os.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\psy.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\registry.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\scales.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\smallft.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\src\window.h">
+      <Filter>liboggvorbis\src</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\include\vorbis\codec.h">
+      <Filter>liboggvorbis\include\vorbis</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\include\vorbis\vorbisenc.h">
+      <Filter>liboggvorbis\include\vorbis</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\include\vorbis\vorbisfile.h">
+      <Filter>liboggvorbis\include\vorbis</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\include\ogg\ogg.h">
+      <Filter>liboggvorbis\include\ogg</Filter>
+    </ClInclude>
+    <ClInclude Include="liboggvorbis\include\ogg\os_types.h">
+      <Filter>liboggvorbis\include\ogg</Filter>
+    </ClInclude>
+    <ClInclude Include="players.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="sdlpal.ico">

+ 161 - 135
sound.c

@@ -20,17 +20,18 @@
 //
 
 #include "palcommon.h"
-#include "common.h"
+#include "global.h"
 #include "sound.h"
-#include "rixplay.h"
+#include "players.h"
 #include "util.h"
+#include "resampler.h"
 
 #ifdef PAL_HAS_NATIVEMIDI
 #include "midi.h"
 #endif
 
-#ifdef PAL_HAS_MP3
-#include "libmad/music_mad.h"
+#if PAL_HAS_OGG
+#include <vorbis/codec.h>
 #endif
 
 static BOOL  gSndOpened = FALSE;
@@ -38,10 +39,6 @@ static BOOL  gSndOpened = FALSE;
 BOOL         g_fNoSound = FALSE;
 BOOL         g_fNoMusic = FALSE;
 
-#ifdef PAL_HAS_NATIVEMIDI
-BOOL         g_fUseMidi = FALSE;
-#endif
-
 static BOOL  g_fUseWav = FALSE;
 
 #ifdef __SYMBIAN32__
@@ -52,6 +49,8 @@ INT          g_iVolume  = SDL_MIX_MAXVOLUME * 0.1;
 int          g_iCurrChannel = 0;
 #endif
 
+#define PAL_CDTRACK_BASE    10000
+
 typedef struct tagSNDPLAYER
 {
    FILE                     *mkf;
@@ -59,15 +58,11 @@ typedef struct tagSNDPLAYER
    SDL_mutex                *mtx;
    LPBYTE                    buf[2], pos[2];
    INT                       audio_len[2];
-#ifdef PAL_HAS_CD
+   MUSICPLAYER              *pMusPlayer;
+   MUSICPLAYER              *pCDPlayer;
+#if PAL_HAS_SDLCD
    SDL_CD                   *pCD;
 #endif
-#ifdef PAL_HAS_MP3
-   mad_data                 *pMP3;
-   BOOL                      fMP3Loop;
-   INT                       iCurrentMP3;
-   SDL_mutex                *lock;
-#endif
 } SNDPLAYER;
 
 static SNDPLAYER gSndPlayer;
@@ -141,7 +136,7 @@ SOUND_LoadVOCFromBuffer(
       //
       // Convert the sample manually, as SDL doesn't like "strange" sample rates.
       //
-      x = (INT)(len * ((FLOAT)PAL_SAMPLE_RATE / freq));
+      x = (INT)(len * ((FLOAT)gpGlobals->iSampleRate / freq));
 
       *lppBuffer = (LPBYTE)calloc(1, x);
       if (*lppBuffer == NULL)
@@ -150,7 +145,7 @@ SOUND_LoadVOCFromBuffer(
       }
       for (i = 0; i < x; i++)
       {
-         l = (INT)(i * (freq / (FLOAT)PAL_SAMPLE_RATE));
+         l = (INT)(i * (freq / (FLOAT)gpGlobals->iSampleRate));
          if (l >= len)
          {
             l = len - 1;
@@ -160,7 +155,7 @@ SOUND_LoadVOCFromBuffer(
 
       lpSpec->channels = 1;
       lpSpec->format = AUDIO_U8;
-      lpSpec->freq = PAL_SAMPLE_RATE;
+      lpSpec->freq = gpGlobals->iSampleRate;
       lpSpec->size = x;
 
 #else
@@ -221,25 +216,17 @@ SOUND_FillAudio(
    //
    if (!g_fNoMusic)
    {
-#ifdef PAL_HAS_MP3
-      SDL_mutexP(gSndPlayer.lock);
+	   SDL_mutexP(gSndPlayer.mtx);
+	   if (gSndPlayer.pMusPlayer)
+	   {
+		   gSndPlayer.pMusPlayer->FillBuffer(gSndPlayer.pMusPlayer, stream, len);
+	   }
 
-      if (gSndPlayer.pMP3 != NULL)
-      {
-         mad_getSamples(gSndPlayer.pMP3, stream, len);
-
-         if (!mad_isPlaying(gSndPlayer.pMP3) && gSndPlayer.fMP3Loop)
-         {
-            mad_seek(gSndPlayer.pMP3, 0);
-            mad_start(gSndPlayer.pMP3);
-
-            mad_getSamples(gSndPlayer.pMP3, stream, len);
-         }
-      }
-
-      SDL_mutexV(gSndPlayer.lock);
-#endif
-      RIX_FillBuffer(stream, len);
+	   if (gSndPlayer.pCDPlayer)
+	   {
+		   gSndPlayer.pCDPlayer->FillBuffer(gSndPlayer.pCDPlayer, stream, len);
+	   }
+	   SDL_mutexV(gSndPlayer.mtx);
    }
 
    //
@@ -307,6 +294,9 @@ SOUND_OpenAudio(
 --*/
 {
    SDL_AudioSpec spec;
+   char *mkfs[2];
+   BOOL use_wave[2];
+   int i;
 
    if (gSndOpened)
    {
@@ -321,27 +311,42 @@ SOUND_OpenAudio(
    //
    // Load the MKF file.
    //
-   gSndPlayer.mkf = UTIL_OpenFile("voc.mkf");
-   if (gSndPlayer.mkf == NULL)
+   if (gpGlobals->fIsWIN95)
    {
-      gSndPlayer.mkf = UTIL_OpenFile("sounds.mkf");
-      if (gSndPlayer.mkf == NULL)
-      {
-         return -2;
-      }
-      g_fUseWav = TRUE;
+	   mkfs[0] = "sounds.mkf"; use_wave[0] = TRUE;
+	   mkfs[1] = "voc.mkf"; use_wave[1] = FALSE;
    }
    else
    {
-      g_fUseWav = FALSE;
+	   mkfs[0] = "voc.mkf"; use_wave[0] = FALSE;
+	   mkfs[1] = "sounds.mkf"; use_wave[1] = TRUE;
+   }
+
+   for (i = 0; i < 2; i++)
+   {
+	   gSndPlayer.mkf = UTIL_OpenFile(mkfs[i]);
+	   if (gSndPlayer.mkf)
+	   {
+		   g_fUseWav = use_wave[i];
+		   break;
+	   }
    }
+   if (gSndPlayer.mkf == NULL)
+   {
+      return -2;
+   }
+
+   //
+   // Initialize the resampler
+   //
+   resampler_init();
 
    //
    // Open the sound subsystem.
    //
-   gSndPlayer.spec.freq = PAL_SAMPLE_RATE;
+   gSndPlayer.spec.freq = gpGlobals->iSampleRate;
    gSndPlayer.spec.format = AUDIO_S16;
-   gSndPlayer.spec.channels = PAL_CHANNELS;
+   gSndPlayer.spec.channels = gpGlobals->iAudioChannels;
    gSndPlayer.spec.samples = 1024;
    gSndPlayer.spec.callback = SOUND_FillAudio;
 
@@ -369,42 +374,79 @@ SOUND_OpenAudio(
    //
    // Initialize the music subsystem.
    //
-   if (RIX_Init(va("%s%s", PAL_PREFIX, "mus.mkf")) < 0)
-   {
-      RIX_Init(va("%s%s", PAL_PREFIX, "MUS.MKF"));
+   switch (gpGlobals->eMusicType)
+   {
+   case MUSIC_RIX:
+	   if (!(gSndPlayer.pMusPlayer = RIX_Init(va("%s%s", PAL_PREFIX, "mus.mkf"))))
+	   {
+		   gSndPlayer.pMusPlayer = RIX_Init(va("%s%s", PAL_PREFIX, "MUS.MKF"));
+	   }
+	   break;
+   case MUSIC_MP3:
+#if PAL_HAS_MP3
+	   gSndPlayer.pMusPlayer = MP3_Init(NULL);
+#else
+	   gSndPlayer.pMusPlayer = NULL;
+#endif
+	   break;
+   case MUSIC_OGG:
+#if PAL_HAS_OGG
+	   gSndPlayer.pMusPlayer = OGG_Init(NULL);
+#else
+	   gSndPlayer.pMusPlayer = NULL;
+#endif
+	   break;
+   case MUSIC_MIDI:
+	   gSndPlayer.pMusPlayer = NULL;
+	   break;
    }
 
-#ifdef PAL_HAS_CD
    //
    // Initialize the CD audio.
    //
-   {
-      int i;
-      gSndPlayer.pCD = NULL;
-
-      for (i = 0; i < SDL_CDNumDrives(); i++)
-      {
-         gSndPlayer.pCD = SDL_CDOpen(i);
-         if (gSndPlayer.pCD != NULL)
-         {
-            if (!CD_INDRIVE(SDL_CDStatus(gSndPlayer.pCD)))
-            {
-               SDL_CDClose(gSndPlayer.pCD);
-               gSndPlayer.pCD = NULL;
-            }
-            else
-            {
-               break;
-            }
-         }
-      }
+   switch (gpGlobals->eCDType)
+   {
+   case MUSIC_SDLCD:
+   {
+#if PAL_HAS_SDLCD
+	   int i;
+	   gSndPlayer.pCD = NULL;
+
+	   for (i = 0; i < SDL_CDNumDrives(); i++)
+	   {
+		   gSndPlayer.pCD = SDL_CDOpen(i);
+		   if (gSndPlayer.pCD != NULL)
+		   {
+			   if (!CD_INDRIVE(SDL_CDStatus(gSndPlayer.pCD)))
+			   {
+				   SDL_CDClose(gSndPlayer.pCD);
+				   gSndPlayer.pCD = NULL;
+			   }
+			   else
+			   {
+				   break;
+			   }
+		   }
+	   }
+#endif
+	   gSndPlayer.pCDPlayer = NULL;
+	   break;
    }
+   case MUSIC_MP3:
+#if PAL_HAS_MP3
+	   gSndPlayer.pCDPlayer = MP3_Init(NULL);
+#else
+	   gSndPlayer.pCDPlayer = NULL;
 #endif
-
-#ifdef PAL_HAS_MP3
-   gSndPlayer.iCurrentMP3 = -1;
-   gSndPlayer.lock = SDL_CreateMutex();
+	   break;
+   case MUSIC_OGG:
+#if PAL_HAS_OGG
+	   gSndPlayer.pCDPlayer = OGG_Init(NULL);
+#else
+	   gSndPlayer.pCDPlayer = NULL;
 #endif
+	   break;
+   }
 
    //
    // Let the callback function run so that musics will be played.
@@ -466,24 +508,19 @@ SOUND_CloseAudio(
       gSndPlayer.mkf = NULL;
    }
 
-   SDL_DestroyMutex(gSndPlayer.mtx);
-
-#ifdef PAL_HAS_MP3
-   SDL_mutexP(gSndPlayer.lock);
-
-   if (gSndPlayer.pMP3 != NULL)
+   if (gSndPlayer.pMusPlayer)
    {
-      mad_stop(gSndPlayer.pMP3);
-      mad_closeFile(gSndPlayer.pMP3);
-      gSndPlayer.pMP3 = NULL;
+	   gSndPlayer.pMusPlayer->Shutdown(gSndPlayer.pMusPlayer);
+	   gSndPlayer.pMusPlayer = NULL;
    }
 
-   SDL_DestroyMutex(gSndPlayer.lock);
-#endif
-
-   RIX_Shutdown();
+   if (gSndPlayer.pCDPlayer)
+   {
+	   gSndPlayer.pCDPlayer->Shutdown(gSndPlayer.pCDPlayer);
+	   gSndPlayer.pCDPlayer = NULL;
+   }
 
-#ifdef PAL_HAS_CD
+#if PAL_HAS_SDLCD
    if (gSndPlayer.pCD != NULL)
    {
       SOUND_PlayCDA(-1);
@@ -494,6 +531,16 @@ SOUND_CloseAudio(
 #ifdef PAL_HAS_NATIVEMIDI
    MIDI_Play(0, FALSE);
 #endif
+
+   SDL_DestroyMutex(gSndPlayer.mtx);
+}
+
+SDL_AudioSpec*
+SOUND_GetAudioSpec(
+	VOID
+)
+{
+	return &gSndPlayer.spec;
 }
 
 #ifdef __SYMBIAN32__
@@ -666,63 +713,27 @@ SOUND_PlayChannel(
 }
 
 VOID
-PAL_PlayMUS(
+SOUND_PlayMUS(
    INT       iNumRIX,
    BOOL      fLoop,
    FLOAT     flFadeTime
 )
 {
+	SDL_mutexP(gSndPlayer.mtx);
+
 #ifdef PAL_HAS_NATIVEMIDI
-   if (g_fUseMidi)
+   if (gpGlobals->eMusicType == MUSIC_MIDI)
    {
       MIDI_Play(iNumRIX, fLoop);
       return;
    }
 #endif
 
-#ifdef PAL_HAS_MP3
-   SDL_mutexP(gSndPlayer.lock);
-
-   if (gSndPlayer.pMP3 != NULL)
+   if (gSndPlayer.pMusPlayer)
    {
-      if (iNumRIX == gSndPlayer.iCurrentMP3 && !g_fNoMusic)
-      {
-         SDL_mutexV(gSndPlayer.lock);
-         return;
-      }
-
-      mad_stop(gSndPlayer.pMP3);
-      mad_closeFile(gSndPlayer.pMP3);
-
-      gSndPlayer.pMP3 = NULL;
-   }
-
-   SDL_mutexV(gSndPlayer.lock);
-
-   gSndPlayer.iCurrentMP3 = -1;
-
-   if (iNumRIX > 0)
-   {
-      SDL_mutexP(gSndPlayer.lock);
-
-      gSndPlayer.pMP3 = mad_openFile(va("%s/mp3/%.2d.mp3", PAL_PREFIX, iNumRIX), &gSndPlayer.spec);
-      if (gSndPlayer.pMP3 != NULL)
-      {
-         RIX_Play(0, FALSE, flFadeTime);
-
-         mad_start(gSndPlayer.pMP3);
-         gSndPlayer.fMP3Loop = fLoop;
-         gSndPlayer.iCurrentMP3 = iNumRIX;
-         SDL_mutexV(gSndPlayer.lock);
-
-         return;
-      }
-
-      SDL_mutexV(gSndPlayer.lock);
+	   gSndPlayer.pMusPlayer->Play(gSndPlayer.pMusPlayer, iNumRIX, fLoop, flFadeTime);
    }
-#endif
-
-   RIX_Play(iNumRIX, fLoop, flFadeTime);
+   SDL_mutexV(gSndPlayer.mtx);
 }
 
 BOOL
@@ -744,7 +755,8 @@ SOUND_PlayCDA(
 
 --*/
 {
-#ifdef PAL_HAS_CD
+	BOOL ret = FALSE;
+#if PAL_HAS_SDLCD
    if (gSndPlayer.pCD != NULL)
    {
       if (CD_INDRIVE(SDL_CDStatus(gSndPlayer.pCD)))
@@ -753,7 +765,7 @@ SOUND_PlayCDA(
 
          if (iNumTrack != -1)
          {
-            PAL_PlayMUS(-1, FALSE, 0);
+            SOUND_PlayMUS(-1, FALSE, 0);
 
             if (SDL_CDPlayTracks(gSndPlayer.pCD, iNumTrack - 1, 0, 1, 0) == 0)
             {
@@ -763,6 +775,20 @@ SOUND_PlayCDA(
       }
    }
 #endif
+   SDL_mutexP(gSndPlayer.mtx);
+   if (gSndPlayer.pCDPlayer)
+   {
+	   if (iNumTrack != -1)
+	   {
+		   SOUND_PlayMUS(-1, FALSE, 0);
+		   ret = gSndPlayer.pCDPlayer->Play(gSndPlayer.pCDPlayer, PAL_CDTRACK_BASE + iNumTrack, TRUE, 0);
+	   }
+	   else
+	   {
+		   ret = gSndPlayer.pCDPlayer->Play(gSndPlayer.pCDPlayer, -1, FALSE, 0);
+	   }
+   }
+   SDL_mutexV(gSndPlayer.mtx);
 
-   return FALSE;
+   return ret;
 }

+ 8 - 10
sound.h

@@ -24,12 +24,8 @@
 
 #include "common.h"
 
-#ifndef PAL_SAMPLE_RATE
-#define PAL_SAMPLE_RATE     44100 /*49716*/
-#endif
-
-#ifndef PAL_CHANNELS
-#define PAL_CHANNELS        2
+#ifndef PAL_MAX_SAMPLERATE
+#define PAL_MAX_SAMPLERATE 48000
 #endif
 
 #ifdef __cplusplus
@@ -53,6 +49,11 @@ SOUND_PlayChannel(
    INT    iChannel
 );
 
+SDL_AudioSpec*
+SOUND_GetAudioSpec(
+   VOID
+);
+
 #ifdef __SYMBIAN32__
 VOID
 SOUND_AdjustVolume(
@@ -61,7 +62,7 @@ SOUND_AdjustVolume(
 #endif
 
 VOID
-PAL_PlayMUS(
+SOUND_PlayMUS(
    INT       iNumRIX,
    BOOL      fLoop,
    FLOAT     flFadeTime
@@ -81,9 +82,6 @@ extern int g_iCurrChannel;
 
 extern BOOL       g_fNoSound;
 extern BOOL       g_fNoMusic;
-#ifdef PAL_HAS_NATIVEMIDI
-extern BOOL       g_fUseMidi;
-#endif
 
 #ifdef __cplusplus
 }

+ 1 - 1
text.c

@@ -41,7 +41,7 @@ BOOL      g_fUpdatedInBattle      = FALSE;
 static const WCHAR* gc_rgszAdditionalWords[CP_MAX][6] = {
    { L"\x6230\x9B25\x901F\x5EA6", L"\x4E00", L"\x4E8C", L"\x4E09", L"\x56DB", L"\x4E94" },
    { L"\x6218\x6597\x901F\x5EA6", L"\x4E00", L"\x4E8C", L"\x4E09", L"\x56DB", L"\x4E94" },
-   { L"\x6226\x95D8\x901F\x3055", L"\x4E00", L"\x4E8C", L"\x4E09", L"\x56DB", L"\x4E94" },
+   { L"\x6226\x95D8\x901F\x5EA6", L"\x4E00", L"\x4E8C", L"\x4E09", L"\x56DB", L"\x4E94" },
 };
 static const WCHAR** g_rgszAdditionalWords;
 #endif

+ 7 - 7
uigame.c

@@ -96,7 +96,7 @@ PAL_OpeningMenu(
    //
    // Play the background music
    //
-   PAL_PlayMUS(RIX_NUM_OPENINGMENU, TRUE, 1);
+   SOUND_PlayMUS(RIX_NUM_OPENINGMENU, TRUE, 1);
 
    //
    // Draw the background
@@ -136,7 +136,7 @@ PAL_OpeningMenu(
    //
    // Fade out the screen and the music
    //
-   PAL_PlayMUS(0, FALSE, 1);
+   SOUND_PlayMUS(0, FALSE, 1);
    PAL_FadeOut(1);
 
    return (INT)wItemSelected;
@@ -619,7 +619,7 @@ PAL_SystemMenu(
       iSlot = PAL_SaveSlotMenu(gpGlobals->bCurrentSaveSlot);
       if (iSlot != MENUITEM_VALUE_CANCELLED)
       {
-         PAL_PlayMUS(0, FALSE, 1);
+         SOUND_PlayMUS(0, FALSE, 1);
          PAL_FadeOut(1);
          PAL_InitGameData(iSlot);
       }
@@ -631,15 +631,15 @@ PAL_SystemMenu(
       //
       g_fNoMusic = !PAL_SwitchMenu(!g_fNoMusic);
 #ifdef PAL_HAS_NATIVEMIDI
-      if (g_fUseMidi)
+      if (gpGlobals->eMusicType == MUSIC_MIDI)
       {
          if (g_fNoMusic)
          {
-            PAL_PlayMUS(0, FALSE, 0);
+            SOUND_PlayMUS(0, FALSE, 0);
          }
          else
          {
-            PAL_PlayMUS(gpGlobals->wNumMusic, TRUE, 0);
+            SOUND_PlayMUS(gpGlobals->wNumMusic, TRUE, 0);
          }
       }
 #endif
@@ -669,7 +669,7 @@ PAL_SystemMenu(
       //
       if (PAL_ConfirmMenu())
       {
-         PAL_PlayMUS(0, FALSE, 2);
+         SOUND_PlayMUS(0, FALSE, 2);
          PAL_FadeOut(2);
          PAL_Shutdown();
          exit(0);