[audacious-plugins/f15] Patch to use system's libmodplug (BR libmodplug-devel).

Michael Schwendt mschwendt at fedoraproject.org
Thu Sep 8 16:49:32 UTC 2011


commit fda145eceffbf6196ca2b300285a4a117b33a8d7
Author: Michael Schwendt <mschwendt at fedoraproject.org>
Date:   Thu Sep 8 18:49:12 2011 +0200

    Patch to use system's libmodplug (BR libmodplug-devel).

 audacious-plugins-2.5.4-libmodplug-system.patch |19943 +++++++++++++++++++++++
 audacious-plugins.spec                          |   13 +-
 2 files changed, 19954 insertions(+), 2 deletions(-)
---
diff --git a/audacious-plugins-2.5.4-libmodplug-system.patch b/audacious-plugins-2.5.4-libmodplug-system.patch
new file mode 100644
index 0000000..59d441d
--- /dev/null
+++ b/audacious-plugins-2.5.4-libmodplug-system.patch
@@ -0,0 +1,19943 @@
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/fastmix.cxx audacious-plugins-2.5.4/src/modplug/fastmix.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/fastmix.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/fastmix.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,1852 +0,0 @@
+-/*
+- * This program is  free software; you can redistribute it  and modify it
+- * under the terms of the GNU  General Public License as published by the
+- * Free Software Foundation; either version 2  of the license or (at your
+- * option) any later version.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+- *          Markus Fick <webmaster at mark-f.de> spline + fir-resampler
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-#include <math.h>
+-
+-// Front Mix Buffer (Also room for interleaved rear mix)
+-int MixSoundBuffer[MIXBUFFERSIZE*4];
+-
+-// Reverb Mix Buffer
+-#ifndef MODPLUG_NO_REVERB
+-int MixReverbBuffer[MIXBUFFERSIZE*2];
+-extern UINT gnReverbSend;
+-#endif
+-
+-int MixRearBuffer[MIXBUFFERSIZE*2];
+-float MixFloatBuffer[MIXBUFFERSIZE*2];
+-
+-
+-extern LONG gnDryROfsVol;
+-extern LONG gnDryLOfsVol;
+-extern LONG gnRvbROfsVol;
+-extern LONG gnRvbLOfsVol;
+-
+-// 4x256 taps polyphase FIR resampling filter
+-extern short int gFastSinc[];
+-extern short int gKaiserSinc[]; // 8-taps polyphase
+-/*
+-  -----------------------------------------------------------------------------
+-   cubic spline interpolation doc,
+-     (derived from "digital image warping", g. wolberg)
+-
+-     interpolation polynomial: f(x) = A3*(x-floor(x))**3 + A2*(x-floor(x))**2 + A1*(x-floor(x)) + A0
+-
+-     with Y = equispaced data points (dist=1), YD = first derivates of data points and IP = floor(x)
+-     the A[0..3] can be found by solving
+-       A0  = Y[IP]
+-       A1  = YD[IP]
+-       A2  = 3*(Y[IP+1]-Y[IP])-2.0*YD[IP]-YD[IP+1]
+-       A3  = -2.0 * (Y[IP+1]-Y[IP]) + YD[IP] - YD[IP+1]
+-
+-     with the first derivates as
+-       YD[IP]    = 0.5 * (Y[IP+1] - Y[IP-1]);
+-       YD[IP+1]  = 0.5 * (Y[IP+2] - Y[IP])
+-
+-     the coefs becomes
+-       A0  = Y[IP]
+-       A1  = YD[IP]
+-           =  0.5 * (Y[IP+1] - Y[IP-1]);
+-       A2  =  3.0 * (Y[IP+1]-Y[IP])-2.0*YD[IP]-YD[IP+1]
+-           =  3.0 * (Y[IP+1] - Y[IP]) - 0.5 * 2.0 * (Y[IP+1] - Y[IP-1]) - 0.5 * (Y[IP+2] - Y[IP])
+-           =  3.0 * Y[IP+1] - 3.0 * Y[IP] - Y[IP+1] + Y[IP-1] - 0.5 * Y[IP+2] + 0.5 * Y[IP]
+-           = -0.5 * Y[IP+2] + 2.0 * Y[IP+1] - 2.5 * Y[IP] + Y[IP-1]
+-	   = Y[IP-1] + 2 * Y[IP+1] - 0.5 * (5.0 * Y[IP] + Y[IP+2])
+-       A3  = -2.0 * (Y[IP+1]-Y[IP]) + YD[IP] + YD[IP+1]
+-           = -2.0 * Y[IP+1] + 2.0 * Y[IP] + 0.5 * (Y[IP+1] - Y[IP-1]) + 0.5 * (Y[IP+2] - Y[IP])
+-           = -2.0 * Y[IP+1] + 2.0 * Y[IP] + 0.5 * Y[IP+1] - 0.5 * Y[IP-1] + 0.5 * Y[IP+2] - 0.5 * Y[IP]
+-           =  0.5 * Y[IP+2] - 1.5 * Y[IP+1] + 1.5 * Y[IP] - 0.5 * Y[IP-1]
+-	   =  0.5 * (3.0 * (Y[IP] - Y[IP+1]) - Y[IP-1] + YP[IP+2])
+-
+-     then interpolated data value is (horner rule)
+-       out = (((A3*x)+A2)*x+A1)*x+A0
+-
+-     this gives parts of data points Y[IP-1] to Y[IP+2] of
+-       part       x**3    x**2    x**1    x**0
+-       Y[IP-1]    -0.5     1      -0.5    0
+-       Y[IP]       1.5    -2.5     0      1
+-       Y[IP+1]    -1.5     2       0.5    0
+-       Y[IP+2]     0.5    -0.5     0      0
+-  -----------------------------------------------------------------------------
+-*/
+-// number of bits used to scale spline coefs
+-#define SPLINE_QUANTBITS	14
+-#define SPLINE_QUANTSCALE	(1L<<SPLINE_QUANTBITS)
+-#define SPLINE_8SHIFT		(SPLINE_QUANTBITS-8)
+-#define SPLINE_16SHIFT		(SPLINE_QUANTBITS)
+-// forces coefsset to unity gain
+-#define SPLINE_CLAMPFORUNITY
+-// log2(number) of precalculated splines (range is [4..14])
+-#define SPLINE_FRACBITS 10
+-#define SPLINE_LUTLEN (1L<<SPLINE_FRACBITS)
+-
+-class CzCUBICSPLINE
+-{	public:
+-		CzCUBICSPLINE( );
+-		~CzCUBICSPLINE( );
+-		static signed short lut[4*(1L<<SPLINE_FRACBITS)];
+-};
+-
+-signed short CzCUBICSPLINE::lut[4*(1L<<SPLINE_FRACBITS)];
+-
+-CzCUBICSPLINE::CzCUBICSPLINE( )
+-{	int _LIi;
+-	int _LLen		= (1L<<SPLINE_FRACBITS);
+-	float _LFlen	= 1.0f / (float)_LLen;
+-	float _LScale	= (float)SPLINE_QUANTSCALE;
+-	for(_LIi=0;_LIi<_LLen;_LIi++)
+-	{	float _LCm1, _LC0, _LC1, _LC2;
+-		float _LX		= ((float)_LIi)*_LFlen;
+-		int _LSum,_LIdx	= _LIi<<2;
+-		_LCm1			= (float)floor( 0.5 + _LScale * (-0.5*_LX*_LX*_LX + 1.0 * _LX*_LX - 0.5 * _LX       ) );
+-		_LC0			= (float)floor( 0.5 + _LScale * ( 1.5*_LX*_LX*_LX - 2.5 * _LX*_LX             + 1.0 ) );
+-		_LC1			= (float)floor( 0.5 + _LScale * (-1.5*_LX*_LX*_LX + 2.0 * _LX*_LX + 0.5 * _LX       ) );
+-		_LC2			= (float)floor( 0.5 + _LScale * ( 0.5*_LX*_LX*_LX - 0.5 * _LX*_LX                   ) );
+-		lut[_LIdx+0]	= (signed short)( (_LCm1 < -_LScale) ? -_LScale : ((_LCm1 > _LScale) ? _LScale : _LCm1) );
+-		lut[_LIdx+1]	= (signed short)( (_LC0  < -_LScale) ? -_LScale : ((_LC0  > _LScale) ? _LScale : _LC0 ) );
+-		lut[_LIdx+2]	= (signed short)( (_LC1  < -_LScale) ? -_LScale : ((_LC1  > _LScale) ? _LScale : _LC1 ) );
+-		lut[_LIdx+3]	= (signed short)( (_LC2  < -_LScale) ? -_LScale : ((_LC2  > _LScale) ? _LScale : _LC2 ) );
+-#ifdef SPLINE_CLAMPFORUNITY
+-		_LSum			= lut[_LIdx+0]+lut[_LIdx+1]+lut[_LIdx+2]+lut[_LIdx+3];
+-		if( _LSum != SPLINE_QUANTSCALE )
+-		{	int _LMax = _LIdx;
+-			if( lut[_LIdx+1]>lut[_LMax] ) _LMax = _LIdx+1;
+-			if( lut[_LIdx+2]>lut[_LMax] ) _LMax = _LIdx+2;
+-			if( lut[_LIdx+3]>lut[_LMax] ) _LMax = _LIdx+3;
+-			lut[_LMax] += (SPLINE_QUANTSCALE-_LSum);
+-		}
+-#endif
+-	}
+-}
+-
+-CzCUBICSPLINE::~CzCUBICSPLINE( )
+-{	// nothing todo
+-}
+-
+-CzCUBICSPLINE sspline;
+-
+-/*
+-  ------------------------------------------------------------------------------------------------
+-   fir interpolation doc,
+-	(derived from "an engineer's guide to fir digital filters", n.j. loy)
+-
+-	calculate coefficients for ideal lowpass filter (with cutoff = fc in 0..1 (mapped to 0..nyquist))
+-	  c[-N..N] = (i==0) ? fc : sin(fc*pi*i)/(pi*i)
+-
+-	then apply selected window to coefficients
+-	  c[-N..N] *= w(0..N)
+-	with n in 2*N and w(n) being a window function (see loy)
+-
+-	then calculate gain and scale filter coefs to have unity gain.
+-  ------------------------------------------------------------------------------------------------
+-*/
+-// quantizer scale of window coefs
+-#define WFIR_QUANTBITS		15
+-#define WFIR_QUANTSCALE		(1L<<WFIR_QUANTBITS)
+-#define WFIR_8SHIFT			(WFIR_QUANTBITS-8)
+-#define WFIR_16BITSHIFT		(WFIR_QUANTBITS)
+-// log2(number)-1 of precalculated taps range is [4..12]
+-#define WFIR_FRACBITS		10
+-#define WFIR_LUTLEN			((1L<<(WFIR_FRACBITS+1))+1)
+-// number of samples in window
+-#define WFIR_LOG2WIDTH		3
+-#define WFIR_WIDTH			(1L<<WFIR_LOG2WIDTH)
+-#define WFIR_SMPSPERWING	((WFIR_WIDTH-1)>>1)
+-// cutoff (1.0 == pi/2)
+-#define WFIR_CUTOFF		0.90f
+-// wfir type
+-#define WFIR_HANN		0
+-#define WFIR_HAMMING		1
+-#define WFIR_BLACKMANEXACT	2
+-#define WFIR_BLACKMAN3T61	3
+-#define WFIR_BLACKMAN3T67	4
+-#define WFIR_BLACKMAN4T92	5
+-#define WFIR_BLACKMAN4T74	6
+-#define WFIR_KAISER4T		7
+-#define WFIR_TYPE		WFIR_BLACKMANEXACT
+-// wfir help
+-#ifndef M_zPI
+-#define M_zPI		3.1415926535897932384626433832795
+-#endif
+-#define M_zEPS		1e-8
+-#define M_zBESSELEPS	1e-21
+-
+-class CzWINDOWEDFIR
+-{	
+-public:
+-	CzWINDOWEDFIR( );
+-	~CzWINDOWEDFIR( );
+-	float coef( int _PCnr, float _POfs, float _PCut, int _PWidth, int _PType ) //float _PPos, float _PFc, int _PLen )
+-	{	
+-		double	_LWidthM1       = _PWidth-1;
+-		double	_LWidthM1Half   = 0.5*_LWidthM1;
+-		double	_LPosU          = ((double)_PCnr - _POfs);
+-		double	_LPos           = _LPosU-_LWidthM1Half;
+-		double	_LPIdl          = 2.0*M_zPI/_LWidthM1;
+-		double	_LWc,_LSi;
+-		if( fabs(_LPos)<M_zEPS ) {	
+-			_LWc	= 1.0;
+-			_LSi	= _PCut;
+-		} else {	
+-			switch( _PType )
+-			{	
+-			case WFIR_HANN:
+-				_LWc = 0.50 - 0.50 * cos(_LPIdl*_LPosU);
+-				break;
+-			case WFIR_HAMMING:
+-				_LWc = 0.54 - 0.46 * cos(_LPIdl*_LPosU);
+-				break;
+-			case WFIR_BLACKMANEXACT:
+-				_LWc = 0.42 - 0.50 * cos(_LPIdl*_LPosU) + 0.08 * cos(2.0*_LPIdl*_LPosU);
+-				break;
+-			case WFIR_BLACKMAN3T61:
+-				_LWc = 0.44959 - 0.49364 * cos(_LPIdl*_LPosU) + 0.05677 * cos(2.0*_LPIdl*_LPosU);
+-				break;
+-			case WFIR_BLACKMAN3T67:
+-				_LWc = 0.42323 - 0.49755 * cos(_LPIdl*_LPosU) + 0.07922 * cos(2.0*_LPIdl*_LPosU);
+-				break;
+-			case WFIR_BLACKMAN4T92:
+-				_LWc = 0.35875 - 0.48829 * cos(_LPIdl*_LPosU) + 0.14128 * cos(2.0*_LPIdl*_LPosU) - 0.01168 * cos(3.0*_LPIdl*_LPosU);
+-				break;
+-			case WFIR_BLACKMAN4T74:
+-				_LWc = 0.40217 - 0.49703 * cos(_LPIdl*_LPosU) + 0.09392 * cos(2.0*_LPIdl*_LPosU) - 0.00183 * cos(3.0*_LPIdl*_LPosU);
+-				break;
+-			case WFIR_KAISER4T:
+-				_LWc = 0.40243 - 0.49804 * cos(_LPIdl*_LPosU) + 0.09831 * cos(2.0*_LPIdl*_LPosU) - 0.00122 * cos(3.0*_LPIdl*_LPosU);
+-				break;
+-			default:
+-				_LWc = 1.0;
+-				break;
+-			}
+-			_LPos	 *= M_zPI;
+-			_LSi	 = sin(_PCut*_LPos)/_LPos;
+-		}
+-		return (float)(_LWc*_LSi);
+-	}
+-	static signed short lut[WFIR_LUTLEN*WFIR_WIDTH];
+-};
+-
+-signed short CzWINDOWEDFIR::lut[WFIR_LUTLEN*WFIR_WIDTH];
+-
+-CzWINDOWEDFIR::CzWINDOWEDFIR()
+-{	
+-	int _LPcl;
+-	float _LPcllen	= (float)(1L<<WFIR_FRACBITS);	// number of precalculated lines for 0..1 (-1..0)
+-	float _LNorm	= 1.0f / (float)(2.0f * _LPcllen);
+-	float _LCut		= WFIR_CUTOFF;
+-	float _LScale	= (float)WFIR_QUANTSCALE;
+-	for( _LPcl=0;_LPcl<WFIR_LUTLEN;_LPcl++ )
+-	{	
+-		float _LGain,_LCoefs[WFIR_WIDTH];
+-		float _LOfs		= ((float)_LPcl-_LPcllen)*_LNorm;
+-		int _LCc,_LIdx	= _LPcl<<WFIR_LOG2WIDTH;
+-		for( _LCc=0,_LGain=0.0f;_LCc<WFIR_WIDTH;_LCc++ )
+-		{	_LGain	+= (_LCoefs[_LCc] = coef( _LCc, _LOfs, _LCut, WFIR_WIDTH, WFIR_TYPE ));
+-		}
+-		_LGain = 1.0f/_LGain;
+-		for( _LCc=0;_LCc<WFIR_WIDTH;_LCc++ )
+-		{	float _LCoef = (float)floor( 0.5 + _LScale*_LCoefs[_LCc]*_LGain );
+-		lut[_LIdx+_LCc] = (signed short)( (_LCoef<-_LScale)?-_LScale:((_LCoef>_LScale)?_LScale:_LCoef) );
+-		}
+-	}
+-}
+-
+-CzWINDOWEDFIR::~CzWINDOWEDFIR()
+-{	// nothing todo
+-}
+-
+-CzWINDOWEDFIR sfir;
+-
+-// ----------------------------------------------------------------------------
+-// MIXING MACROS
+-// ----------------------------------------------------------------------------
+-/////////////////////////////////////////////////////
+-// Mixing Macros
+-
+-#define SNDMIX_BEGINSAMPLELOOP8\
+-	register MODCHANNEL * const pChn = pChannel;\
+-	nPos = pChn->nPosLo;\
+-	const signed char *p = (signed char *)(pChn->pCurrentSample+pChn->nPos);\
+-	if (pChn->dwFlags & CHN_STEREO) p += pChn->nPos;\
+-	int *pvol = pbuffer;\
+-	do {
+-
+-#define SNDMIX_BEGINSAMPLELOOP16\
+-	register MODCHANNEL * const pChn = pChannel;\
+-	nPos = pChn->nPosLo;\
+-	const signed short *p = (signed short *)(pChn->pCurrentSample+(pChn->nPos*2));\
+-	if (pChn->dwFlags & CHN_STEREO) p += pChn->nPos;\
+-	int *pvol = pbuffer;\
+-	do {
+-
+-#define SNDMIX_ENDSAMPLELOOP\
+-		nPos += pChn->nInc;\
+-	} while (pvol < pbufmax);\
+-	pChn->nPos += nPos >> 16;\
+-	pChn->nPosLo = nPos & 0xFFFF;
+-
+-#define SNDMIX_ENDSAMPLELOOP8	SNDMIX_ENDSAMPLELOOP
+-#define SNDMIX_ENDSAMPLELOOP16	SNDMIX_ENDSAMPLELOOP
+-
+-//////////////////////////////////////////////////////////////////////////////
+-// Mono
+-
+-// No interpolation
+-#define SNDMIX_GETMONOVOL8NOIDO\
+-	int vol = p[nPos >> 16] << 8;
+-
+-#define SNDMIX_GETMONOVOL16NOIDO\
+-	int vol = p[nPos >> 16];
+-
+-// Linear Interpolation
+-#define SNDMIX_GETMONOVOL8LINEAR\
+-	int poshi = nPos >> 16;\
+-	int poslo = (nPos >> 8) & 0xFF;\
+-	int srcvol = p[poshi];\
+-	int destvol = p[poshi+1];\
+-	int vol = (srcvol<<8) + ((int)(poslo * (destvol - srcvol)));
+-
+-#define SNDMIX_GETMONOVOL16LINEAR\
+-	int poshi = nPos >> 16;\
+-	int poslo = (nPos >> 8) & 0xFF;\
+-	int srcvol = p[poshi];\
+-	int destvol = p[poshi+1];\
+-	int vol = srcvol + ((int)(poslo * (destvol - srcvol)) >> 8);
+-
+-// spline interpolation (2 guard bits should be enough???)
+-#define SPLINE_FRACSHIFT ((16-SPLINE_FRACBITS)-2)
+-#define SPLINE_FRACMASK  (((1L<<(16-SPLINE_FRACSHIFT))-1)&~3)
+-
+-#define SNDMIX_GETMONOVOL8SPLINE \
+-	int poshi	= nPos >> 16; \
+-	int poslo	= (nPos >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \
+-	int vol		= (CzCUBICSPLINE::lut[poslo  ]*(int)p[poshi-1] + \
+-	               CzCUBICSPLINE::lut[poslo+1]*(int)p[poshi  ] + \
+-	               CzCUBICSPLINE::lut[poslo+3]*(int)p[poshi+2] + \
+-	               CzCUBICSPLINE::lut[poslo+2]*(int)p[poshi+1]) >> SPLINE_8SHIFT;
+-	
+-#define SNDMIX_GETMONOVOL16SPLINE \
+-	int poshi	= nPos >> 16; \
+-	int poslo	= (nPos >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \
+-	int vol		= (CzCUBICSPLINE::lut[poslo  ]*(int)p[poshi-1] + \
+-	               CzCUBICSPLINE::lut[poslo+1]*(int)p[poshi  ] + \
+-	               CzCUBICSPLINE::lut[poslo+3]*(int)p[poshi+2] + \
+-	               CzCUBICSPLINE::lut[poslo+2]*(int)p[poshi+1]) >> SPLINE_16SHIFT;
+-
+-
+-// fir interpolation
+-#define WFIR_FRACSHIFT	(16-(WFIR_FRACBITS+1+WFIR_LOG2WIDTH))
+-#define WFIR_FRACMASK	((((1L<<(17-WFIR_FRACSHIFT))-1)&~((1L<<WFIR_LOG2WIDTH)-1)))
+-#define WFIR_FRACHALVE	(1L<<(16-(WFIR_FRACBITS+2)))
+-
+-#define SNDMIX_GETMONOVOL8FIRFILTER \
+-	int poshi  = nPos >> 16;\
+-	int poslo  = (nPos & 0xFFFF);\
+-	int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \
+-	int vol    = (CzWINDOWEDFIR::lut[firidx+0]*(int)p[poshi+1-4]);	\
+-            vol   += (CzWINDOWEDFIR::lut[firidx+1]*(int)p[poshi+2-4]);	\
+-            vol   += (CzWINDOWEDFIR::lut[firidx+2]*(int)p[poshi+3-4]);	\
+-            vol   += (CzWINDOWEDFIR::lut[firidx+3]*(int)p[poshi+4-4]);	\
+-            vol   += (CzWINDOWEDFIR::lut[firidx+4]*(int)p[poshi+5-4]);	\
+-            vol   += (CzWINDOWEDFIR::lut[firidx+5]*(int)p[poshi+6-4]);	\
+-            vol   += (CzWINDOWEDFIR::lut[firidx+6]*(int)p[poshi+7-4]);	\
+-            vol   += (CzWINDOWEDFIR::lut[firidx+7]*(int)p[poshi+8-4]);	\
+-            vol  >>= WFIR_8SHIFT;
+-
+-#define SNDMIX_GETMONOVOL16FIRFILTER \
+-    int poshi  = nPos >> 16;\
+-    int poslo  = (nPos & 0xFFFF);\
+-    int firidx = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \
+-    int vol1   = (CzWINDOWEDFIR::lut[firidx+0]*(int)p[poshi+1-4]);	\
+-        vol1  += (CzWINDOWEDFIR::lut[firidx+1]*(int)p[poshi+2-4]);	\
+-        vol1  += (CzWINDOWEDFIR::lut[firidx+2]*(int)p[poshi+3-4]);	\
+-        vol1  += (CzWINDOWEDFIR::lut[firidx+3]*(int)p[poshi+4-4]);	\
+-    int vol2   = (CzWINDOWEDFIR::lut[firidx+4]*(int)p[poshi+5-4]);	\
+-	vol2  += (CzWINDOWEDFIR::lut[firidx+5]*(int)p[poshi+6-4]);	\
+-	vol2  += (CzWINDOWEDFIR::lut[firidx+6]*(int)p[poshi+7-4]);	\
+-	vol2  += (CzWINDOWEDFIR::lut[firidx+7]*(int)p[poshi+8-4]);	\
+-    int vol    = ((vol1>>1)+(vol2>>1)) >> (WFIR_16BITSHIFT-1);
+-
+-/////////////////////////////////////////////////////////////////////////////
+-// Stereo
+-
+-// No interpolation
+-#define SNDMIX_GETSTEREOVOL8NOIDO\
+-    int vol_l = p[(nPos>>16)*2] << 8;\
+-    int vol_r = p[(nPos>>16)*2+1] << 8;
+-
+-#define SNDMIX_GETSTEREOVOL16NOIDO\
+-    int vol_l = p[(nPos>>16)*2];\
+-    int vol_r = p[(nPos>>16)*2+1];
+-
+-// Linear Interpolation
+-#define SNDMIX_GETSTEREOVOL8LINEAR\
+-    int poshi = nPos >> 16;\
+-    int poslo = (nPos >> 8) & 0xFF;\
+-    int srcvol_l = p[poshi*2];\
+-    int vol_l = (srcvol_l<<8) + ((int)(poslo * (p[poshi*2+2] - srcvol_l)));\
+-    int srcvol_r = p[poshi*2+1];\
+-    int vol_r = (srcvol_r<<8) + ((int)(poslo * (p[poshi*2+3] - srcvol_r)));
+-
+-#define SNDMIX_GETSTEREOVOL16LINEAR\
+-    int poshi = nPos >> 16;\
+-    int poslo = (nPos >> 8) & 0xFF;\
+-    int srcvol_l = p[poshi*2];\
+-    int vol_l = srcvol_l + ((int)(poslo * (p[poshi*2+2] - srcvol_l)) >> 8);\
+-    int srcvol_r = p[poshi*2+1];\
+-    int vol_r = srcvol_r + ((int)(poslo * (p[poshi*2+3] - srcvol_r)) >> 8);\
+-
+-// Spline Interpolation
+-#define SNDMIX_GETSTEREOVOL8SPLINE \
+-    int poshi	= nPos >> 16; \
+-    int poslo	= (nPos >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \
+-    int vol_l	= (CzCUBICSPLINE::lut[poslo  ]*(int)p[(poshi-1)*2  ] + \
+-	           CzCUBICSPLINE::lut[poslo+1]*(int)p[(poshi  )*2  ] + \
+-	           CzCUBICSPLINE::lut[poslo+2]*(int)p[(poshi+1)*2  ] + \
+-	           CzCUBICSPLINE::lut[poslo+3]*(int)p[(poshi+2)*2  ]) >> SPLINE_8SHIFT; \
+-    int vol_r	= (CzCUBICSPLINE::lut[poslo  ]*(int)p[(poshi-1)*2+1] + \
+-	           CzCUBICSPLINE::lut[poslo+1]*(int)p[(poshi  )*2+1] + \
+-	           CzCUBICSPLINE::lut[poslo+2]*(int)p[(poshi+1)*2+1] + \
+-	           CzCUBICSPLINE::lut[poslo+3]*(int)p[(poshi+2)*2+1]) >> SPLINE_8SHIFT;
+-
+-#define SNDMIX_GETSTEREOVOL16SPLINE \
+-    int poshi	= nPos >> 16; \
+-    int poslo	= (nPos >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \
+-    int vol_l	= (CzCUBICSPLINE::lut[poslo  ]*(int)p[(poshi-1)*2  ] + \
+-	           CzCUBICSPLINE::lut[poslo+1]*(int)p[(poshi  )*2  ] + \
+-	           CzCUBICSPLINE::lut[poslo+2]*(int)p[(poshi+1)*2  ] + \
+-	           CzCUBICSPLINE::lut[poslo+3]*(int)p[(poshi+2)*2  ]) >> SPLINE_16SHIFT; \
+-    int vol_r	= (CzCUBICSPLINE::lut[poslo  ]*(int)p[(poshi-1)*2+1] + \
+-	           CzCUBICSPLINE::lut[poslo+1]*(int)p[(poshi  )*2+1] + \
+-	           CzCUBICSPLINE::lut[poslo+2]*(int)p[(poshi+1)*2+1] + \
+-	           CzCUBICSPLINE::lut[poslo+3]*(int)p[(poshi+2)*2+1]) >> SPLINE_16SHIFT;
+-
+-// fir interpolation
+-#define SNDMIX_GETSTEREOVOL8FIRFILTER \
+-    int poshi   = nPos >> 16;\
+-    int poslo   = (nPos & 0xFFFF);\
+-    int firidx  = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \
+-    int vol_l   = (CzWINDOWEDFIR::lut[firidx+0]*(int)p[(poshi+1-4)*2  ]);   \
+-	vol_l  += (CzWINDOWEDFIR::lut[firidx+1]*(int)p[(poshi+2-4)*2  ]);   \
+-	vol_l  += (CzWINDOWEDFIR::lut[firidx+2]*(int)p[(poshi+3-4)*2  ]);   \
+-        vol_l  += (CzWINDOWEDFIR::lut[firidx+3]*(int)p[(poshi+4-4)*2  ]);   \
+-        vol_l  += (CzWINDOWEDFIR::lut[firidx+4]*(int)p[(poshi+5-4)*2  ]);   \
+-	vol_l  += (CzWINDOWEDFIR::lut[firidx+5]*(int)p[(poshi+6-4)*2  ]);   \
+-	vol_l  += (CzWINDOWEDFIR::lut[firidx+6]*(int)p[(poshi+7-4)*2  ]);   \
+-        vol_l  += (CzWINDOWEDFIR::lut[firidx+7]*(int)p[(poshi+8-4)*2  ]);   \
+-	vol_l >>= WFIR_8SHIFT; \
+-    int vol_r   = (CzWINDOWEDFIR::lut[firidx+0]*(int)p[(poshi+1-4)*2+1]);   \
+-	vol_r  += (CzWINDOWEDFIR::lut[firidx+1]*(int)p[(poshi+2-4)*2+1]);   \
+-	vol_r  += (CzWINDOWEDFIR::lut[firidx+2]*(int)p[(poshi+3-4)*2+1]);   \
+-	vol_r  += (CzWINDOWEDFIR::lut[firidx+3]*(int)p[(poshi+4-4)*2+1]);   \
+-	vol_r  += (CzWINDOWEDFIR::lut[firidx+4]*(int)p[(poshi+5-4)*2+1]);   \
+-        vol_r  += (CzWINDOWEDFIR::lut[firidx+5]*(int)p[(poshi+6-4)*2+1]);   \
+-        vol_r  += (CzWINDOWEDFIR::lut[firidx+6]*(int)p[(poshi+7-4)*2+1]);   \
+-        vol_r  += (CzWINDOWEDFIR::lut[firidx+7]*(int)p[(poshi+8-4)*2+1]);   \
+-        vol_r >>= WFIR_8SHIFT;
+-
+-#define SNDMIX_GETSTEREOVOL16FIRFILTER \
+-    int poshi   = nPos >> 16;\
+-    int poslo   = (nPos & 0xFFFF);\
+-    int firidx  = ((poslo+WFIR_FRACHALVE)>>WFIR_FRACSHIFT) & WFIR_FRACMASK; \
+-    int vol1_l  = (CzWINDOWEDFIR::lut[firidx+0]*(int)p[(poshi+1-4)*2  ]);   \
+-	vol1_l += (CzWINDOWEDFIR::lut[firidx+1]*(int)p[(poshi+2-4)*2  ]);   \
+-        vol1_l += (CzWINDOWEDFIR::lut[firidx+2]*(int)p[(poshi+3-4)*2  ]);   \
+-	vol1_l += (CzWINDOWEDFIR::lut[firidx+3]*(int)p[(poshi+4-4)*2  ]);   \
+-   int vol2_l  = (CzWINDOWEDFIR::lut[firidx+4]*(int)p[(poshi+5-4)*2  ]);    \
+-       vol2_l += (CzWINDOWEDFIR::lut[firidx+5]*(int)p[(poshi+6-4)*2  ]);    \
+-       vol2_l += (CzWINDOWEDFIR::lut[firidx+6]*(int)p[(poshi+7-4)*2  ]);    \
+-       vol2_l += (CzWINDOWEDFIR::lut[firidx+7]*(int)p[(poshi+8-4)*2  ]);    \
+-   int vol_l   = ((vol1_l>>1)+(vol2_l>>1)) >> (WFIR_16BITSHIFT-1); \
+-   int vol1_r  = (CzWINDOWEDFIR::lut[firidx+0]*(int)p[(poshi+1-4)*2+1]);    \
+-       vol1_r += (CzWINDOWEDFIR::lut[firidx+1]*(int)p[(poshi+2-4)*2+1]);    \
+-       vol1_r += (CzWINDOWEDFIR::lut[firidx+2]*(int)p[(poshi+3-4)*2+1]);    \
+-       vol1_r += (CzWINDOWEDFIR::lut[firidx+3]*(int)p[(poshi+4-4)*2+1]);    \
+-   int vol2_r  = (CzWINDOWEDFIR::lut[firidx+4]*(int)p[(poshi+5-4)*2+1]);    \
+-       vol2_r += (CzWINDOWEDFIR::lut[firidx+5]*(int)p[(poshi+6-4)*2+1]);    \
+-       vol2_r += (CzWINDOWEDFIR::lut[firidx+6]*(int)p[(poshi+7-4)*2+1]);    \
+-       vol2_r += (CzWINDOWEDFIR::lut[firidx+7]*(int)p[(poshi+8-4)*2+1]);    \
+-   int vol_r   = ((vol1_r>>1)+(vol2_r>>1)) >> (WFIR_16BITSHIFT-1);
+-
+-/////////////////////////////////////////////////////////////////////////////
+-
+-#define SNDMIX_STOREMONOVOL\
+-	pvol[0] += vol * pChn->nRightVol;\
+-	pvol[1] += vol * pChn->nLeftVol;\
+-	pvol += 2;
+-
+-#define SNDMIX_STORESTEREOVOL\
+-	pvol[0] += vol_l * pChn->nRightVol;\
+-	pvol[1] += vol_r * pChn->nLeftVol;\
+-	pvol += 2;
+-
+-#define SNDMIX_STOREFASTMONOVOL\
+-	int v = vol * pChn->nRightVol;\
+-	pvol[0] += v;\
+-	pvol[1] += v;\
+-	pvol += 2;
+-
+-#define SNDMIX_RAMPMONOVOL\
+-	nRampLeftVol += pChn->nLeftRamp;\
+-	nRampRightVol += pChn->nRightRamp;\
+-	pvol[0] += vol * (nRampRightVol >> VOLUMERAMPPRECISION);\
+-	pvol[1] += vol * (nRampLeftVol >> VOLUMERAMPPRECISION);\
+-	pvol += 2;
+-
+-#define SNDMIX_RAMPFASTMONOVOL\
+-	nRampRightVol += pChn->nRightRamp;\
+-	int fastvol = vol * (nRampRightVol >> VOLUMERAMPPRECISION);\
+-	pvol[0] += fastvol;\
+-	pvol[1] += fastvol;\
+-	pvol += 2;
+-
+-#define SNDMIX_RAMPSTEREOVOL\
+-	nRampLeftVol += pChn->nLeftRamp;\
+-	nRampRightVol += pChn->nRightRamp;\
+-	pvol[0] += vol_l * (nRampRightVol >> VOLUMERAMPPRECISION);\
+-	pvol[1] += vol_r * (nRampLeftVol >> VOLUMERAMPPRECISION);\
+-	pvol += 2;
+-
+-
+-///////////////////////////////////////////////////
+-// Resonant Filters
+-
+-// Mono
+-#define MIX_BEGIN_FILTER \
+-	double fy1 = pChannel->nFilter_Y1;\
+-	double fy2 = pChannel->nFilter_Y2;\
+-	double ta;
+-
+-#define MIX_END_FILTER \
+-	pChannel->nFilter_Y1 = fy1;\
+-	pChannel->nFilter_Y2 = fy2;
+-
+-#define SNDMIX_PROCESSFILTER \
+-ta = ((double)vol * pChn->nFilter_A0 + fy1 * pChn->nFilter_B0 + fy2 * pChn->nFilter_B1);\
+-fy2 = fy1;\
+-fy1 = ta;vol=(int)ta;
+-
+-// Stereo
+-#define MIX_BEGIN_STEREO_FILTER \
+-double fy1 = pChannel->nFilter_Y1;\
+-double fy2 = pChannel->nFilter_Y2;\
+-double fy3 = pChannel->nFilter_Y3;\
+-double fy4 = pChannel->nFilter_Y4;\
+-double ta, tb;
+-
+-#define MIX_END_STEREO_FILTER \
+-pChannel->nFilter_Y1 = fy1;\
+-pChannel->nFilter_Y2 = fy2;\
+-pChannel->nFilter_Y3 = fy3;\
+-pChannel->nFilter_Y4 = fy4;\
+-
+-#define SNDMIX_PROCESSSTEREOFILTER \
+-ta = ((double)vol_l * pChn->nFilter_A0 + fy1 * pChn->nFilter_B0 + fy2 * pChn->nFilter_B1);\
+-tb = ((double)vol_r * pChn->nFilter_A0 + fy3 * pChn->nFilter_B0 + fy4 * pChn->nFilter_B1);\
+-fy2 = fy1; fy1 = ta;vol_l=(int)ta;\
+-fy4 = fy3; fy3 = tb;vol_r=(int)tb;
+-
+-//////////////////////////////////////////////////////////
+-// Interfaces
+-
+-typedef VOID (MPPASMCALL * LPMIXINTERFACE)(MODCHANNEL *, int *, int *);
+-
+-#define BEGIN_MIX_INTERFACE(func)\
+-	VOID MPPASMCALL func(MODCHANNEL *pChannel, int *pbuffer, int *pbufmax)\
+-	{\
+-		LONG nPos;
+-
+-#define END_MIX_INTERFACE()\
+-		SNDMIX_ENDSAMPLELOOP\
+-	}
+-
+-// Volume Ramps
+-#define BEGIN_RAMPMIX_INTERFACE(func)\
+-	BEGIN_MIX_INTERFACE(func)\
+-		LONG nRampRightVol = pChannel->nRampRightVol;\
+-		LONG nRampLeftVol = pChannel->nRampLeftVol;
+-
+-#define END_RAMPMIX_INTERFACE()\
+-		SNDMIX_ENDSAMPLELOOP\
+-		pChannel->nRampRightVol = nRampRightVol;\
+-		pChannel->nRightVol = nRampRightVol >> VOLUMERAMPPRECISION;\
+-		pChannel->nRampLeftVol = nRampLeftVol;\
+-		pChannel->nLeftVol = nRampLeftVol >> VOLUMERAMPPRECISION;\
+-	}
+-
+-#define BEGIN_FASTRAMPMIX_INTERFACE(func)\
+-	BEGIN_MIX_INTERFACE(func)\
+-		LONG nRampRightVol = pChannel->nRampRightVol;
+-
+-#define END_FASTRAMPMIX_INTERFACE()\
+-		SNDMIX_ENDSAMPLELOOP\
+-		pChannel->nRampRightVol = nRampRightVol;\
+-		pChannel->nRampLeftVol = nRampRightVol;\
+-		pChannel->nRightVol = nRampRightVol >> VOLUMERAMPPRECISION;\
+-		pChannel->nLeftVol = pChannel->nRightVol;\
+-	}
+-
+-
+-// Mono Resonant Filters
+-#define BEGIN_MIX_FLT_INTERFACE(func)\
+-	BEGIN_MIX_INTERFACE(func)\
+-	MIX_BEGIN_FILTER
+-
+-
+-#define END_MIX_FLT_INTERFACE()\
+-	SNDMIX_ENDSAMPLELOOP\
+-	MIX_END_FILTER\
+-	}
+-
+-#define BEGIN_RAMPMIX_FLT_INTERFACE(func)\
+-	BEGIN_MIX_INTERFACE(func)\
+-		LONG nRampRightVol = pChannel->nRampRightVol;\
+-		LONG nRampLeftVol = pChannel->nRampLeftVol;\
+-		MIX_BEGIN_FILTER
+-
+-#define END_RAMPMIX_FLT_INTERFACE()\
+-		SNDMIX_ENDSAMPLELOOP\
+-		MIX_END_FILTER\
+-		pChannel->nRampRightVol = nRampRightVol;\
+-		pChannel->nRightVol = nRampRightVol >> VOLUMERAMPPRECISION;\
+-		pChannel->nRampLeftVol = nRampLeftVol;\
+-		pChannel->nLeftVol = nRampLeftVol >> VOLUMERAMPPRECISION;\
+-	}
+-
+-// Stereo Resonant Filters
+-#define BEGIN_MIX_STFLT_INTERFACE(func)\
+-	BEGIN_MIX_INTERFACE(func)\
+-	MIX_BEGIN_STEREO_FILTER
+-
+-
+-#define END_MIX_STFLT_INTERFACE()\
+-	SNDMIX_ENDSAMPLELOOP\
+-	MIX_END_STEREO_FILTER\
+-	}
+-
+-#define BEGIN_RAMPMIX_STFLT_INTERFACE(func)\
+-	BEGIN_MIX_INTERFACE(func)\
+-		LONG nRampRightVol = pChannel->nRampRightVol;\
+-		LONG nRampLeftVol = pChannel->nRampLeftVol;\
+-		MIX_BEGIN_STEREO_FILTER
+-
+-#define END_RAMPMIX_STFLT_INTERFACE()\
+-		SNDMIX_ENDSAMPLELOOP\
+-		MIX_END_STEREO_FILTER\
+-		pChannel->nRampRightVol = nRampRightVol;\
+-		pChannel->nRightVol = nRampRightVol >> VOLUMERAMPPRECISION;\
+-		pChannel->nRampLeftVol = nRampLeftVol;\
+-		pChannel->nLeftVol = nRampLeftVol >> VOLUMERAMPPRECISION;\
+-	}
+-
+-
+-/////////////////////////////////////////////////////
+-//
+-
+-extern void StereoMixToFloat(const int *pSrc, float *pOut1, float *pOut2, UINT nCount, const float _i2fc);
+-extern void FloatToStereoMix(const float *pIn1, const float *pIn2, int *pOut, UINT nCount, const float _f2ic);
+-extern void MonoMixToFloat(const int *pSrc, float *pOut, UINT nCount, const float _i2fc);
+-extern void FloatToMonoMix(const float *pIn, int *pOut, UINT nCount, const float _f2ic);
+-
+-void InitMixBuffer(int *pBuffer, UINT nSamples);
+-void EndChannelOfs(MODCHANNEL *pChannel, int *pBuffer, UINT nSamples);
+-void StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs);
+-
+-void StereoMixToFloat(const int *, float *, float *, UINT nCount);
+-void FloatToStereoMix(const float *pIn1, const float *pIn2, int *pOut, UINT nCount);
+-
+-/////////////////////////////////////////////////////
+-// Mono samples functions
+-
+-BEGIN_MIX_INTERFACE(Mono8BitMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8NOIDO
+-	SNDMIX_STOREMONOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(Mono16BitMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16NOIDO
+-	SNDMIX_STOREMONOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(Mono8BitLinearMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8LINEAR
+-	SNDMIX_STOREMONOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(Mono16BitLinearMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16LINEAR
+-	SNDMIX_STOREMONOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(Mono8BitSplineMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8SPLINE
+-	SNDMIX_STOREMONOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(Mono16BitSplineMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16SPLINE
+-	SNDMIX_STOREMONOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(Mono8BitFirFilterMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8FIRFILTER
+-	SNDMIX_STOREMONOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(Mono16BitFirFilterMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16FIRFILTER
+-	SNDMIX_STOREMONOVOL
+-END_MIX_INTERFACE()
+-
+-
+-// Volume Ramps
+-BEGIN_RAMPMIX_INTERFACE(Mono8BitRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8NOIDO
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-BEGIN_RAMPMIX_INTERFACE(Mono16BitRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16NOIDO
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-BEGIN_RAMPMIX_INTERFACE(Mono8BitLinearRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8LINEAR
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-BEGIN_RAMPMIX_INTERFACE(Mono16BitLinearRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16LINEAR
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-BEGIN_RAMPMIX_INTERFACE(Mono8BitSplineRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8SPLINE
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-BEGIN_RAMPMIX_INTERFACE(Mono16BitSplineRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16SPLINE
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-BEGIN_RAMPMIX_INTERFACE(Mono8BitFirFilterRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8FIRFILTER
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-BEGIN_RAMPMIX_INTERFACE(Mono16BitFirFilterRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16FIRFILTER
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-
+-//////////////////////////////////////////////////////
+-// Fast mono mix for leftvol=rightvol (1 less imul)
+-
+-BEGIN_MIX_INTERFACE(FastMono8BitMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8NOIDO
+-	SNDMIX_STOREFASTMONOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(FastMono16BitMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16NOIDO
+-	SNDMIX_STOREFASTMONOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(FastMono8BitLinearMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8LINEAR
+-	SNDMIX_STOREFASTMONOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(FastMono16BitLinearMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16LINEAR
+-	SNDMIX_STOREFASTMONOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(FastMono8BitSplineMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8SPLINE
+-	SNDMIX_STOREFASTMONOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(FastMono16BitSplineMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16SPLINE
+-	SNDMIX_STOREFASTMONOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(FastMono8BitFirFilterMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8FIRFILTER
+-	SNDMIX_STOREFASTMONOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(FastMono16BitFirFilterMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16FIRFILTER
+-	SNDMIX_STOREFASTMONOVOL
+-END_MIX_INTERFACE()
+-
+-
+-// Fast Ramps
+-BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8NOIDO
+-	SNDMIX_RAMPFASTMONOVOL
+-END_FASTRAMPMIX_INTERFACE()
+-
+-BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16NOIDO
+-	SNDMIX_RAMPFASTMONOVOL
+-END_FASTRAMPMIX_INTERFACE()
+-
+-BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitLinearRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8LINEAR
+-	SNDMIX_RAMPFASTMONOVOL
+-END_FASTRAMPMIX_INTERFACE()
+-
+-BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitLinearRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16LINEAR
+-	SNDMIX_RAMPFASTMONOVOL
+-END_FASTRAMPMIX_INTERFACE()
+-
+-BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitSplineRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8SPLINE
+-	SNDMIX_RAMPFASTMONOVOL
+-END_FASTRAMPMIX_INTERFACE()
+-
+-BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitSplineRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16SPLINE
+-	SNDMIX_RAMPFASTMONOVOL
+-END_FASTRAMPMIX_INTERFACE()
+-
+-BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitFirFilterRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8FIRFILTER
+-	SNDMIX_RAMPFASTMONOVOL
+-END_FASTRAMPMIX_INTERFACE()
+-
+-BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitFirFilterRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16FIRFILTER
+-	SNDMIX_RAMPFASTMONOVOL
+-END_FASTRAMPMIX_INTERFACE()
+-
+-
+-//////////////////////////////////////////////////////
+-// Stereo samples
+-
+-BEGIN_MIX_INTERFACE(Stereo8BitMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8NOIDO
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(Stereo16BitMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16NOIDO
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(Stereo8BitLinearMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8LINEAR
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(Stereo16BitLinearMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16LINEAR
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(Stereo8BitSplineMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8SPLINE
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(Stereo16BitSplineMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16SPLINE
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(Stereo8BitFirFilterMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8FIRFILTER
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_INTERFACE()
+-
+-BEGIN_MIX_INTERFACE(Stereo16BitFirFilterMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16FIRFILTER
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_INTERFACE()
+-
+-
+-// Volume Ramps
+-BEGIN_RAMPMIX_INTERFACE(Stereo8BitRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8NOIDO
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-BEGIN_RAMPMIX_INTERFACE(Stereo16BitRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16NOIDO
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-BEGIN_RAMPMIX_INTERFACE(Stereo8BitLinearRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8LINEAR
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-BEGIN_RAMPMIX_INTERFACE(Stereo16BitLinearRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16LINEAR
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-BEGIN_RAMPMIX_INTERFACE(Stereo8BitSplineRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8SPLINE
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-BEGIN_RAMPMIX_INTERFACE(Stereo16BitSplineRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16SPLINE
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-BEGIN_RAMPMIX_INTERFACE(Stereo8BitFirFilterRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8FIRFILTER
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-BEGIN_RAMPMIX_INTERFACE(Stereo16BitFirFilterRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16FIRFILTER
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_INTERFACE()
+-
+-
+-
+-//////////////////////////////////////////////////////
+-// Resonant Filter Mix
+-
+-#ifndef NO_FILTER
+-
+-// Mono Filter Mix
+-BEGIN_MIX_FLT_INTERFACE(FilterMono8BitMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8NOIDO
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_STOREMONOVOL
+-END_MIX_FLT_INTERFACE()
+-
+-BEGIN_MIX_FLT_INTERFACE(FilterMono16BitMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16NOIDO
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_STOREMONOVOL
+-END_MIX_FLT_INTERFACE()
+-
+-BEGIN_MIX_FLT_INTERFACE(FilterMono8BitLinearMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8LINEAR
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_STOREMONOVOL
+-END_MIX_FLT_INTERFACE()
+-
+-BEGIN_MIX_FLT_INTERFACE(FilterMono16BitLinearMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16LINEAR
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_STOREMONOVOL
+-END_MIX_FLT_INTERFACE()
+-
+-BEGIN_MIX_FLT_INTERFACE(FilterMono8BitSplineMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8SPLINE
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_STOREMONOVOL
+-END_MIX_FLT_INTERFACE()
+-
+-BEGIN_MIX_FLT_INTERFACE(FilterMono16BitSplineMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16SPLINE
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_STOREMONOVOL
+-END_MIX_FLT_INTERFACE()
+-
+-BEGIN_MIX_FLT_INTERFACE(FilterMono8BitFirFilterMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8FIRFILTER
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_STOREMONOVOL
+-END_MIX_FLT_INTERFACE()
+-
+-BEGIN_MIX_FLT_INTERFACE(FilterMono16BitFirFilterMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16FIRFILTER
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_STOREMONOVOL
+-END_MIX_FLT_INTERFACE()
+-
+-// Filter + Ramp
+-BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8NOIDO
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_FLT_INTERFACE()
+-
+-BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16NOIDO
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_FLT_INTERFACE()
+-
+-BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitLinearRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8LINEAR
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_FLT_INTERFACE()
+-
+-BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitLinearRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16LINEAR
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_FLT_INTERFACE()
+-
+-BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitSplineRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8SPLINE
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_FLT_INTERFACE()
+-
+-BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitSplineRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16SPLINE
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_FLT_INTERFACE()
+-
+-BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitFirFilterRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETMONOVOL8FIRFILTER
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_FLT_INTERFACE()
+-
+-BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitFirFilterRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETMONOVOL16FIRFILTER
+-	SNDMIX_PROCESSFILTER
+-	SNDMIX_RAMPMONOVOL
+-END_RAMPMIX_FLT_INTERFACE()
+-
+-
+-// Stereo Filter Mix
+-BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8NOIDO
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_STFLT_INTERFACE()
+-
+-BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16NOIDO
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_STFLT_INTERFACE()
+-
+-BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitLinearMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8LINEAR
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_STFLT_INTERFACE()
+-
+-BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitLinearMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16LINEAR
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_STFLT_INTERFACE()
+-
+-BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitSplineMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8SPLINE
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_STFLT_INTERFACE()
+-
+-BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitSplineMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16SPLINE
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_STFLT_INTERFACE()
+-
+-BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitFirFilterMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8FIRFILTER
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_STFLT_INTERFACE()
+-
+-BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitFirFilterMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16FIRFILTER
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_STORESTEREOVOL
+-END_MIX_STFLT_INTERFACE()
+-
+-// Stereo Filter + Ramp
+-BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8NOIDO
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_STFLT_INTERFACE()
+-
+-BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16NOIDO
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_STFLT_INTERFACE()
+-
+-BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitLinearRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8LINEAR
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_STFLT_INTERFACE()
+-
+-BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitLinearRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16LINEAR
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_STFLT_INTERFACE()
+-
+-BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitSplineRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8SPLINE
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_STFLT_INTERFACE()
+-
+-BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitSplineRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16SPLINE
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_STFLT_INTERFACE()
+-
+-BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitFirFilterRampMix)
+-	SNDMIX_BEGINSAMPLELOOP8
+-	SNDMIX_GETSTEREOVOL8FIRFILTER
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_STFLT_INTERFACE()
+-
+-BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitFirFilterRampMix)
+-	SNDMIX_BEGINSAMPLELOOP16
+-	SNDMIX_GETSTEREOVOL16FIRFILTER
+-	SNDMIX_PROCESSSTEREOFILTER
+-	SNDMIX_RAMPSTEREOVOL
+-END_RAMPMIX_STFLT_INTERFACE()
+-
+-
+-#else
+-// Mono
+-#define FilterMono8BitMix					Mono8BitMix
+-#define FilterMono16BitMix					Mono16BitMix
+-#define FilterMono8BitLinearMix				Mono8BitLinearMix
+-#define FilterMono16BitLinearMix			Mono16BitLinearMix
+-#define FilterMono8BitSplineMix				Mono8BitSplineMix
+-#define FilterMono16BitSplineMix			Mono16BitSplineMix
+-#define FilterMono8BitFirFilterMix			Mono8BitFirFilterMix
+-#define FilterMono16BitFirFilterMix			Mono16BitFirFilterMix
+-#define FilterMono8BitRampMix				Mono8BitRampMix
+-#define FilterMono16BitRampMix				Mono16BitRampMix
+-#define FilterMono8BitLinearRampMix			Mono8BitLinearRampMix
+-#define FilterMono16BitLinearRampMix		Mono16BitLinearRampMix
+-#define FilterMono8BitSplineRampMix			Mono8BitSplineRampMix
+-#define FilterMono16BitSplineRampMix		Mono16BitSplineRampMix
+-#define FilterMono8BitFirFilterRampMix		Mono8BitFirFilterRampMix
+-#define FilterMono16BitFirFilterRampMix		Mono16BitFirFilterRampMix
+-// Stereo
+-#define FilterStereo8BitMix					Stereo8BitMix
+-#define FilterStereo16BitMix				Stereo16BitMix
+-#define FilterStereo8BitLinearMix			Stereo8BitLinearMix
+-#define FilterStereo16BitLinearMix			Stereo16BitLinearMix
+-#define FilterStereo8BitSplineMix			Stereo8BitSplineMix
+-#define FilterStereo16BitSplineMix			Stereo16BitSplineMix
+-#define FilterStereo8BitFirFilterMix		Stereo8BitFirFilterMix
+-#define FilterStereo16BitFirFilterMix		Stereo16BitFirFilterMix
+-#define FilterStereo8BitRampMix				Stereo8BitRampMix
+-#define FilterStereo16BitRampMix			Stereo16BitRampMix
+-#define FilterStereo8BitLinearRampMix		Stereo8BitLinearRampMix
+-#define FilterStereo16BitLinearRampMix		Stereo16BitLinearRampMix
+-#define FilterStereo8BitSplineRampMix		Stereo8BitSplineRampMix
+-#define FilterStereo16BitSplineRampMix		Stereo16BitSplineRampMix
+-#define FilterStereo8BitFirFilterRampMix	Stereo8BitFirFilterRampMix
+-#define FilterStereo16BitFirFilterRampMix	Stereo16BitFirFilterRampMix
+-
+-#endif
+-
+-/////////////////////////////////////////////////////////////////////////////////////
+-//
+-// Mix function tables
+-//
+-//
+-// Index is as follow:
+-//	[b1-b0]	format (8-bit-mono, 16-bit-mono, 8-bit-stereo, 16-bit-stereo)
+-//	[b2]	ramp
+-//	[b3]	filter
+-//	[b5-b4]	src type
+-//
+-
+-#define MIXNDX_16BIT        0x01
+-#define MIXNDX_STEREO       0x02
+-#define MIXNDX_RAMP         0x04
+-#define MIXNDX_FILTER       0x08
+-#define MIXNDX_LINEARSRC    0x10
+-#define MIXNDX_SPLINESRC    0x20
+-#define MIXNDX_FIRSRC       0x30
+-
+-const LPMIXINTERFACE gpMixFunctionTable[2*2*16] =
+-{
+-	// No SRC
+-	Mono8BitMix, Mono16BitMix, Stereo8BitMix, Stereo16BitMix,
+-	Mono8BitRampMix, Mono16BitRampMix, Stereo8BitRampMix, 
+-            Stereo16BitRampMix,
+-	// No SRC, Filter
+-	FilterMono8BitMix, FilterMono16BitMix, FilterStereo8BitMix, 
+-        FilterStereo16BitMix, FilterMono8BitRampMix, FilterMono16BitRampMix, 
+-	FilterStereo8BitRampMix, FilterStereo16BitRampMix,
+-	// Linear SRC
+-	Mono8BitLinearMix, Mono16BitLinearMix, Stereo8BitLinearMix,
+-	Stereo16BitLinearMix, Mono8BitLinearRampMix, Mono16BitLinearRampMix,
+-	Stereo8BitLinearRampMix,Stereo16BitLinearRampMix,
+-	// Linear SRC, Filter
+-	FilterMono8BitLinearMix, FilterMono16BitLinearMix, 
+-        FilterStereo8BitLinearMix, FilterStereo16BitLinearMix,
+-	FilterMono8BitLinearRampMix, FilterMono16BitLinearRampMix,
+-        FilterStereo8BitLinearRampMix, FilterStereo16BitLinearRampMix,
+-
+-	// FirFilter SRC
+-	Mono8BitSplineMix, Mono16BitSplineMix, Stereo8BitSplineMix, 
+-        Stereo16BitSplineMix, Mono8BitSplineRampMix, Mono16BitSplineRampMix,
+-	Stereo8BitSplineRampMix,Stereo16BitSplineRampMix,
+-	// Spline SRC, Filter
+-	FilterMono8BitSplineMix, FilterMono16BitSplineMix, 
+-        FilterStereo8BitSplineMix, FilterStereo16BitSplineMix,
+-	FilterMono8BitSplineRampMix, FilterMono16BitSplineRampMix,
+-        FilterStereo8BitSplineRampMix, FilterStereo16BitSplineRampMix,
+-
+-	// FirFilter  SRC
+-	Mono8BitFirFilterMix, Mono16BitFirFilterMix, Stereo8BitFirFilterMix,
+-	Stereo16BitFirFilterMix, Mono8BitFirFilterRampMix, 
+-        Mono16BitFirFilterRampMix, Stereo8BitFirFilterRampMix, 
+-        Stereo16BitFirFilterRampMix,
+-	// FirFilter  SRC, Filter
+-	FilterMono8BitFirFilterMix, FilterMono16BitFirFilterMix, 
+-        FilterStereo8BitFirFilterMix, FilterStereo16BitFirFilterMix,
+-	FilterMono8BitFirFilterRampMix, FilterMono16BitFirFilterRampMix,
+-        FilterStereo8BitFirFilterRampMix, FilterStereo16BitFirFilterRampMix
+-};
+-
+-const LPMIXINTERFACE gpFastMixFunctionTable[2*2*16] =
+-{
+-	// No SRC
+-	FastMono8BitMix, FastMono16BitMix, Stereo8BitMix, Stereo16BitMix,
+-	FastMono8BitRampMix, FastMono16BitRampMix, Stereo8BitRampMix,
+-        Stereo16BitRampMix,
+-	// No SRC, Filter
+-	FilterMono8BitMix, FilterMono16BitMix, FilterStereo8BitMix, 
+-        FilterStereo16BitMix, FilterMono8BitRampMix, FilterMono16BitRampMix,
+-        FilterStereo8BitRampMix, FilterStereo16BitRampMix,
+-	// Linear SRC
+-	FastMono8BitLinearMix, FastMono16BitLinearMix, Stereo8BitLinearMix,
+-        Stereo16BitLinearMix, FastMono8BitLinearRampMix, 
+-        FastMono16BitLinearRampMix, Stereo8BitLinearRampMix, 
+-        Stereo16BitLinearRampMix,
+-	// Linear SRC, Filter
+-	FilterMono8BitLinearMix, FilterMono16BitLinearMix, 
+-        FilterStereo8BitLinearMix, FilterStereo16BitLinearMix,
+-	FilterMono8BitLinearRampMix, FilterMono16BitLinearRampMix, 
+-        FilterStereo8BitLinearRampMix, FilterStereo16BitLinearRampMix,
+-
+-	// Spline SRC
+-	Mono8BitSplineMix, Mono16BitSplineMix, Stereo8BitSplineMix, 
+-        Stereo16BitSplineMix, Mono8BitSplineRampMix, Mono16BitSplineRampMix,
+-        Stereo8BitSplineRampMix, Stereo16BitSplineRampMix,
+-	// Spline SRC, Filter
+-	FilterMono8BitSplineMix, FilterMono16BitSplineMix, 
+-        FilterStereo8BitSplineMix, FilterStereo16BitSplineMix,
+-	FilterMono8BitSplineRampMix, FilterMono16BitSplineRampMix, 
+-        FilterStereo8BitSplineRampMix, FilterStereo16BitSplineRampMix,
+-
+-	// FirFilter SRC
+-	Mono8BitFirFilterMix, Mono16BitFirFilterMix, Stereo8BitFirFilterMix,
+-        Stereo16BitFirFilterMix, Mono8BitFirFilterRampMix, 
+-        Mono16BitFirFilterRampMix, Stereo8BitFirFilterRampMix, 
+-        Stereo16BitFirFilterRampMix,
+-	// FirFilter SRC, Filter
+-	FilterMono8BitFirFilterMix, FilterMono16BitFirFilterMix, 
+-        FilterStereo8BitFirFilterMix, FilterStereo16BitFirFilterMix,
+-	FilterMono8BitFirFilterRampMix, FilterMono16BitFirFilterRampMix, 
+-        FilterStereo8BitFirFilterRampMix, FilterStereo16BitFirFilterRampMix,
+-};
+-
+-
+-/////////////////////////////////////////////////////////////////////////
+-
+-static LONG MPPFASTCALL GetSampleCount(MODCHANNEL *pChn, LONG nSamples)
+-//---------------------------------------------------------------------
+-{
+-	LONG nLoopStart = (pChn->dwFlags & CHN_LOOP) ? pChn->nLoopStart : 0;
+-	LONG nInc = pChn->nInc;
+-
+-	if ((nSamples <= 0) || (!nInc) || (!pChn->nLength)) return 0;
+-	// Under zero ?
+-	if ((LONG)pChn->nPos < nLoopStart)
+-	{
+-		if (nInc < 0)
+-		{
+-			// Invert loop for bidi loops
+-			LONG nDelta = ((nLoopStart - pChn->nPos) << 16) - (pChn->nPosLo & 0xffff);
+-			pChn->nPos = nLoopStart | (nDelta>>16);
+-			pChn->nPosLo = nDelta & 0xffff;
+-			if (((LONG)pChn->nPos < nLoopStart) || (pChn->nPos >= (nLoopStart+pChn->nLength)/2))
+-			{
+-				pChn->nPos = nLoopStart; pChn->nPosLo = 0;
+-			}
+-			nInc = -nInc;
+-			pChn->nInc = nInc;
+-			pChn->dwFlags &= ~(CHN_PINGPONGFLAG); // go forward
+-			if ((!(pChn->dwFlags & CHN_LOOP)) || (pChn->nPos >= pChn->nLength))
+-			{
+-				pChn->nPos = pChn->nLength;
+-				pChn->nPosLo = 0;
+-				return 0;
+-			}
+-		} else
+-		{
+-			// We probably didn't hit the loop end yet (first loop), so we do nothing
+-			if ((LONG)pChn->nPos < 0) pChn->nPos = 0;
+-		}
+-	} else
+-	// Past the end
+-	if (pChn->nPos >= pChn->nLength)
+-	{
+-		if (!(pChn->dwFlags & CHN_LOOP)) return 0; // not looping -> stop this channel
+-		if (pChn->dwFlags & CHN_PINGPONGLOOP)
+-		{
+-			// Invert loop
+-			if (nInc > 0)
+-			{
+-				nInc = -nInc;
+-				pChn->nInc = nInc;
+-			}
+-			pChn->dwFlags |= CHN_PINGPONGFLAG;
+-			// adjust loop position
+-			LONG nDeltaHi = (pChn->nPos - pChn->nLength);
+-			LONG nDeltaLo = 0x10000 - (pChn->nPosLo & 0xffff);
+-			pChn->nPos = pChn->nLength - nDeltaHi - (nDeltaLo>>16);
+-			pChn->nPosLo = nDeltaLo & 0xffff;
+-			if ((pChn->nPos <= pChn->nLoopStart) || (pChn->nPos >= pChn->nLength)) pChn->nPos = pChn->nLength-1;
+-		} else
+-		{
+-			if (nInc < 0) // This is a bug
+-			{
+-				nInc = -nInc;
+-				pChn->nInc = nInc;
+-			}
+-			// Restart at loop start
+-			pChn->nPos += nLoopStart - pChn->nLength;
+-			if ((LONG)pChn->nPos < nLoopStart) pChn->nPos = pChn->nLoopStart;
+-		}
+-	}
+-	LONG nPos = pChn->nPos;
+-	// too big increment, and/or too small loop length
+-	if (nPos < nLoopStart)
+-	{
+-		if ((nPos < 0) || (nInc < 0)) return 0;
+-	}
+-	if ((nPos < 0) || (nPos >= (LONG)pChn->nLength)) return 0;
+-	LONG nPosLo = (USHORT)pChn->nPosLo, nSmpCount = nSamples;
+-	if (nInc < 0)
+-	{
+-		LONG nInv = -nInc;
+-		LONG maxsamples = 16384 / ((nInv>>16)+1);
+-		if (maxsamples < 2) maxsamples = 2;
+-		if (nSamples > maxsamples) nSamples = maxsamples;
+-		LONG nDeltaHi = (nInv>>16) * (nSamples - 1);
+-		LONG nDeltaLo = (nInv&0xffff) * (nSamples - 1);
+-		LONG nPosDest = nPos - nDeltaHi + ((nPosLo - nDeltaLo) >> 16);
+-		if (nPosDest < nLoopStart)
+-		{
+-			nSmpCount = (ULONG)(((((LONGLONG)nPos - nLoopStart) << 16) + nPosLo - 1) / nInv) + 1;
+-		}
+-	} else
+-	{
+-		LONG maxsamples = 16384 / ((nInc>>16)+1);
+-		if (maxsamples < 2) maxsamples = 2;
+-		if (nSamples > maxsamples) nSamples = maxsamples;
+-		LONG nDeltaHi = (nInc>>16) * (nSamples - 1);
+-		LONG nDeltaLo = (nInc&0xffff) * (nSamples - 1);
+-		LONG nPosDest = nPos + nDeltaHi + ((nPosLo + nDeltaLo)>>16);
+-		if (nPosDest >= (LONG)pChn->nLength)
+-		{
+-			nSmpCount = (ULONG)(((((LONGLONG)pChn->nLength - nPos) << 16) - nPosLo - 1) / nInc) + 1;
+-		}
+-	}
+-	if (nSmpCount <= 1) return 1;
+-	if (nSmpCount > nSamples) return nSamples;
+-	return nSmpCount;
+-}
+-
+-
+-UINT CSoundFile::CreateStereoMix(int count)
+-//-----------------------------------------
+-{
+-	LPLONG pOfsL, pOfsR;
+-	DWORD nchused, nchmixed;
+-
+-	if (!count) return 0;
+-	if (gnChannels > 2) InitMixBuffer(MixRearBuffer, count*2);
+-	nchused = nchmixed = 0;
+-	for (UINT nChn=0; nChn<m_nMixChannels; nChn++)
+-	{
+-		const LPMIXINTERFACE *pMixFuncTable;
+-		MODCHANNEL * const pChannel = &Chn[ChnMix[nChn]];
+-		UINT nFlags;
+-		LONG nSmpCount;
+-		int nsamples;
+-		int *pbuffer;
+-
+-		if (!pChannel->pCurrentSample) continue;
+-		pOfsR = &gnDryROfsVol;
+-		pOfsL = &gnDryLOfsVol;
+-		nFlags = 0;
+-		if (pChannel->dwFlags & CHN_16BIT) nFlags |= MIXNDX_16BIT;
+-		if (pChannel->dwFlags & CHN_STEREO) nFlags |= MIXNDX_STEREO;
+-	#ifndef NO_FILTER
+-		if (pChannel->dwFlags & CHN_FILTER) nFlags |= MIXNDX_FILTER;
+-	#endif
+-		if (!(pChannel->dwFlags & CHN_NOIDO)
+-		&& !(gdwSoundSetup & SNDMIX_NORESAMPLING))
+-		{
+-			// use hq-fir mixer?
+-			if( (gdwSoundSetup & (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE)) == (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE) )
+-				nFlags |= MIXNDX_FIRSRC;
+-			else if( (gdwSoundSetup & SNDMIX_HQRESAMPLER))
+-				nFlags |= MIXNDX_SPLINESRC;
+-			else
+-				nFlags |= MIXNDX_LINEARSRC; // use
+-		}
+-		if ((nFlags < 0x40) && (pChannel->nLeftVol == pChannel->nRightVol)
+-		 && ((!pChannel->nRampLength) || (pChannel->nLeftRamp == pChannel->nRightRamp)))
+-		{
+-			pMixFuncTable = gpFastMixFunctionTable;
+-		} else
+-		{
+-			pMixFuncTable = gpMixFunctionTable;
+-		}
+-		nsamples = count;
+-#ifndef MODPLUG_NO_REVERB
+-		pbuffer = (gdwSoundSetup & SNDMIX_REVERB) ? MixReverbBuffer : MixSoundBuffer;
+-		if (pChannel->dwFlags & CHN_NOREVERB) pbuffer = MixSoundBuffer;
+-		if (pChannel->dwFlags & CHN_REVERB) pbuffer = MixReverbBuffer;
+-		if (pbuffer == MixReverbBuffer)
+-		{
+-			if (!gnReverbSend) memset(MixReverbBuffer, 0, count * 8);
+-			gnReverbSend += count;
+-		}
+-#else
+-		pbuffer = MixSoundBuffer;
+-#endif
+-		nchused++;
+-		////////////////////////////////////////////////////
+-	SampleLooping:
+-		UINT nrampsamples = nsamples;
+-		if (pChannel->nRampLength > 0)
+-		{
+-			if ((LONG)nrampsamples > pChannel->nRampLength) nrampsamples = pChannel->nRampLength;
+-		}
+-		if ((nSmpCount = GetSampleCount(pChannel, nrampsamples)) <= 0)
+-		{
+-			// Stopping the channel
+-			pChannel->pCurrentSample = NULL;
+-			pChannel->nLength = 0;
+-			pChannel->nPos = 0;
+-			pChannel->nPosLo = 0;
+-			pChannel->nRampLength = 0;
+-			EndChannelOfs(pChannel, pbuffer, nsamples);
+-			*pOfsR += pChannel->nROfs;
+-			*pOfsL += pChannel->nLOfs;
+-			pChannel->nROfs = pChannel->nLOfs = 0;
+-			pChannel->dwFlags &= ~CHN_PINGPONGFLAG;
+-			continue;
+-		}
+-		// Should we mix this channel ?
+-		UINT naddmix;
+-		if (((nchmixed >= m_nMaxMixChannels) && (!(gdwSoundSetup & SNDMIX_DIRECTTODISK)))
+-		 || ((!pChannel->nRampLength) && (!(pChannel->nLeftVol|pChannel->nRightVol))))
+-		{
+-			LONG delta = (pChannel->nInc * (LONG)nSmpCount) + (LONG)pChannel->nPosLo;
+-			pChannel->nPosLo = delta & 0xFFFF;
+-			pChannel->nPos += (delta >> 16);
+-			pChannel->nROfs = pChannel->nLOfs = 0;
+-			pbuffer += nSmpCount*2;
+-			naddmix = 0;
+-		} else
+-		// Do mixing
+-		{
+-			if (pChannel->nLength) {
+-				pChannel->topnote_offset = ((pChannel->nPos << 16) | pChannel->nPosLo) % pChannel->nLength;
+-			}
+-
+-			// Choose function for mixing
+-			LPMIXINTERFACE pMixFunc;
+-			pMixFunc = (pChannel->nRampLength) ? pMixFuncTable[nFlags|MIXNDX_RAMP] : pMixFuncTable[nFlags];
+-			int *pbufmax = pbuffer + (nSmpCount*2);
+-			pChannel->nROfs = - *(pbufmax-2);
+-			pChannel->nLOfs = - *(pbufmax-1);
+-			pMixFunc(pChannel, pbuffer, pbufmax);
+-			pChannel->nROfs += *(pbufmax-2);
+-			pChannel->nLOfs += *(pbufmax-1);
+-			pbuffer = pbufmax;
+-			naddmix = 1;
+-
+-		}
+-		nsamples -= nSmpCount;
+-		if (pChannel->nRampLength)
+-		{
+-			pChannel->nRampLength -= nSmpCount;
+-			if (pChannel->nRampLength <= 0)
+-			{
+-				pChannel->nRampLength = 0;
+-				pChannel->nRightVol = pChannel->nNewRightVol;
+-				pChannel->nLeftVol = pChannel->nNewLeftVol;
+-				pChannel->nRightRamp = pChannel->nLeftRamp = 0;
+-				if ((pChannel->dwFlags & CHN_NOTEFADE) && (!(pChannel->nFadeOutVol)))
+-				{
+-					pChannel->nLength = 0;
+-					pChannel->pCurrentSample = NULL;
+-				}
+-			}
+-		}
+-		if (nsamples > 0) goto SampleLooping;
+-		nchmixed += naddmix;
+-	}
+-	return nchused;
+-}
+-
+-static float f2ic = (float)(1 << 28);
+-static float i2fc = (float)(1.0 / (1 << 28));
+-
+-VOID CSoundFile::StereoMixToFloat(const int *pSrc, float *pOut1, float *pOut2, UINT nCount)
+-//-----------------------------------------------------------------------------------------
+-{
+-	for (UINT i = 0; i < nCount; i++) {
+-		*pOut1++ = *pSrc * i2fc; /*!*/
+-		pSrc++;
+-
+-		*pOut2++ = *pSrc * i2fc; /*!*/
+-		pSrc++;
+-	}
+-}
+-
+-
+-VOID CSoundFile::FloatToStereoMix(const float *pIn1, const float *pIn2, int *pOut, UINT nCount)
+-//---------------------------------------------------------------------------------------------
+-{
+-	for (UINT i = 0; i < nCount; i++) {
+-		*pOut++ = (int)(*pIn1 * f2ic);
+-		*pOut++ = (int)(*pIn2 * f2ic);
+-		pIn1++;
+-		pIn2++;
+-	}
+-}
+-
+-
+-VOID CSoundFile::MonoMixToFloat(const int *pSrc, float *pOut, UINT nCount)
+-//------------------------------------------------------------------------
+-{
+-	for (UINT i = 0; i < nCount; i++) {
+-		*pOut++ = *pSrc * i2fc; /*!*/
+-		pSrc++;
+-	}
+-}
+-
+-
+-VOID CSoundFile::FloatToMonoMix(const float *pIn, int *pOut, UINT nCount)
+-//-----------------------------------------------------------------------
+-{
+-	for (UINT i = 0; i < nCount; i++) {
+-		*pOut++ = (int)(*pIn * f2ic); /*!*/
+-		pIn++;
+-	}
+-}
+-
+-
+-// Clip and convert to 8 bit
+-//---GCCFIX: Asm replaced with C function
+-// The C version was written by Rani Assaf <rani at magic.metawire.com>, I believe
+-DWORD Convert32To8(LPVOID lp8, int *pBuffer, DWORD lSampleCount, LONG mins[2], LONG maxs[2])
+-{
+-	unsigned char *p = (unsigned char *)lp8;
+-	for (UINT i=0; i<lSampleCount; i++)
+-	{
+-		int n = pBuffer[i];
+-		if (n < MIXING_CLIPMIN)
+-			n = MIXING_CLIPMIN;
+-		else if (n > MIXING_CLIPMAX)
+-			n = MIXING_CLIPMAX;
+-		if (n < mins[i&1])
+-			mins[i&1]= n;
+-		else if (n > maxs[i&1])
+-			maxs[i&1] = n;
+-		p[i] = (n >> (24-MIXING_ATTENUATION)) ^ 0x80;	// 8-bit unsigned
+-	}
+-	return lSampleCount;
+-}
+-//---GCCFIX: Asm replaced with C function
+-// The C version was written by Rani Assaf <rani at magic.metawire.com>, I believe
+-DWORD Convert32To16(LPVOID lp16, int *pBuffer, DWORD lSampleCount, LONG mins[2], LONG maxs[2])
+-{
+-	signed short *p = (signed short *)lp16;
+-	for (UINT i=0; i<lSampleCount; i++)
+-	{
+-		int n = pBuffer[i];
+-		if (n < MIXING_CLIPMIN)
+-			n = MIXING_CLIPMIN;
+-		else if (n > MIXING_CLIPMAX)
+-			n = MIXING_CLIPMAX;
+-		if (n < mins[i&1])
+-			mins[i&1]= n;
+-		else if (n > maxs[i&1])
+-			maxs[i&1] = n;
+-		p[i] = n >> (16-MIXING_ATTENUATION);	// 16-bit signed
+-	}
+-	return lSampleCount * 2;
+-}
+-//---GCCFIX: Asm replaced with C function
+-// 24-bit might not work...
+-DWORD Convert32To24(LPVOID lp24, int *pBuffer, DWORD lSampleCount, LONG mins[2], LONG maxs[2])
+-{
+-	/* the inventor of 24bit anything should be shot */
+-	unsigned char *p = (unsigned char *)lp24;
+-	for (UINT i=0; i<lSampleCount; i++)
+-	{
+-		int n = pBuffer[i];
+-		if (n < MIXING_CLIPMIN)
+-			n = MIXING_CLIPMIN;
+-		else if (n > MIXING_CLIPMAX)
+-			n = MIXING_CLIPMAX;
+-		if (n < mins[i&1])
+-			mins[i&1]= n;
+-		else if (n > maxs[i&1])
+-			maxs[i&1] = n;
+-		n = n >> (8-MIXING_ATTENUATION);	// 24-bit signed
+-		/* err, assume same endian */
+-		memcpy(p, &n, 3);
+-		p += 3;
+-	}
+-	return lSampleCount * 2;
+-}
+-//---GCCFIX: Asm replaced with C function
+-// 32-bit might not work...
+-DWORD Convert32To32(LPVOID lp32, int *pBuffer, DWORD lSampleCount, LONG mins[2], LONG maxs[2])
+-{
+-	signed int *p = (signed int *)lp32;
+-	for (UINT i=0; i<lSampleCount; i++)
+-	{
+-		int n = pBuffer[i];
+-		if (n < MIXING_CLIPMIN)
+-			n = MIXING_CLIPMIN;
+-		else if (n > MIXING_CLIPMAX)
+-			n = MIXING_CLIPMAX;
+-		if (n < mins[i&1])
+-			mins[i&1]= n;
+-		else if (n > maxs[i&1])
+-			maxs[i&1] = n;
+-		p[i] = (n >> MIXING_ATTENUATION);	// 32-bit signed
+-	}
+-	return lSampleCount * 2;
+-}
+-//---GCCFIX: Asm replaced with C function
+-// Will fill in later.
+-void InitMixBuffer(int *pBuffer, UINT nSamples)
+-{
+-	memset(pBuffer, 0, nSamples * sizeof(int));
+-}
+-
+-//---GCCFIX: Asm replaced with C function
+-void InterleaveFrontRear(int *pFrontBuf, int *pRearBuf, DWORD nSamples)
+-{
+-	DWORD i=0;
+-
+-	pRearBuf[i] = pFrontBuf[1];
+-	for (i = 1; i < nSamples; i++) {
+-		pRearBuf[i] = pFrontBuf[(i*2)+1];
+-		pFrontBuf[i] = pFrontBuf[i*2];
+-	}
+-}
+-//---GCCFIX: Asm replaced with C function
+-VOID MonoFromStereo(int *pMixBuf, UINT nSamples)
+-{
+-	UINT j;
+-	for(UINT i = 0; i < nSamples; i++)
+-	{
+-		j = i << 1;
+-		pMixBuf[i] = (pMixBuf[j] + pMixBuf[j + 1]) >> 1;
+-	}
+-}
+-
+-//---GCCFIX: Asm replaced with C function
+-#define OFSDECAYSHIFT    8
+-#define OFSDECAYMASK     0xFF
+-void StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs)
+-//---------------------------------------------------------------------------------------------------------
+-{
+-	int rofs = *lpROfs;
+-	int lofs = *lpLOfs;
+-
+-	if ((!rofs) && (!lofs))
+-	{
+-		InitMixBuffer(pBuffer, nSamples*2);
+-		return;
+-	}
+-	for (UINT i=0; i<nSamples; i++)
+-	{
+-		int x_r = (rofs + (((-rofs)>>31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
+-		int x_l = (lofs + (((-lofs)>>31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
+-		rofs -= x_r;
+-		lofs -= x_l;
+-		pBuffer[i*2] = x_r;
+-		pBuffer[i*2+1] = x_l;
+-	}
+-	*lpROfs = rofs;
+-	*lpLOfs = lofs;
+-}
+-//---GCCFIX: Asm replaced with C function
+-// Will fill in later.
+-void EndChannelOfs(MODCHANNEL *pChannel, int *pBuffer, UINT nSamples)
+-{
+-	int rofs = pChannel->nROfs;
+-	int lofs = pChannel->nLOfs;
+-
+-	if ((!rofs) && (!lofs)) return;
+-	for (UINT i=0; i<nSamples; i++)
+-	{
+-		int x_r = (rofs + (((-rofs)>>31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
+-		int x_l = (lofs + (((-lofs)>>31) & OFSDECAYMASK)) >> OFSDECAYSHIFT;
+-		rofs -= x_r;
+-		lofs -= x_l;
+-		pBuffer[i*2] += x_r;
+-		pBuffer[i*2+1] += x_l;
+-	}
+-	pChannel->nROfs = rofs;
+-	pChannel->nLOfs = lofs;
+-}
+-
+-
+-
+-
+-
+-//////////////////////////////////////////////////////////////////////////////////
+-// Automatic Gain Control
+-
+-#ifndef NO_AGC
+-
+-// Limiter
+-#define MIXING_LIMITMAX		(0x08100000)
+-#define MIXING_LIMITMIN		(-MIXING_LIMITMAX)
+-
+-void CSoundFile::ProcessAGC(int count)
+-//------------------------------------
+-{
+-	static DWORD gAGCRecoverCount = 0;
+-	UINT agc = AGC(MixSoundBuffer, count, gnAGC);
+-	// Some kind custom law, so that the AGC stays quite stable, but slowly
+-	// goes back up if the sound level stays below a level inversely proportional
+-	// to the AGC level. (J'me comprends)
+-	if ((agc >= gnAGC) && (gnAGC < AGC_UNITY) && (gnVUMeter < (0xFF - (gnAGC >> (AGC_PRECISION-7))) ))
+-	{
+-		gAGCRecoverCount += count;
+-		UINT agctimeout = gdwMixingFreq + gnAGC;
+-		if (gnChannels >= 2) agctimeout <<= 1;
+-		if (gAGCRecoverCount >= agctimeout)
+-		{
+-			gAGCRecoverCount = 0;
+-			gnAGC++;
+-		}
+-	} else
+-	{
+-		gnAGC = agc;
+-		gAGCRecoverCount = 0;
+-	}
+-}
+-
+-
+-
+-void CSoundFile::ResetAGC()
+-//-------------------------
+-{
+-	gnAGC = AGC_UNITY;
+-}
+-
+-#endif // NO_AGC
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/gui/main.cxx audacious-plugins-2.5.4/src/modplug/gui/main.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/gui/main.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/gui/main.cxx	2011-09-08 18:43:07.016726319 +0200
+@@ -6,8 +6,8 @@
+ #include <config.h>
+ 
+ #include "../stddefs.h"
+-#include "../stdafx.h"
+-#include "../sndfile.h"
++#include "stdafx.h"
++#include "sndfile.h"
+ #include "../archive/open.h"
+ 
+ // Order of #include is important - UINT is redefined to unsigned long instead of unsigned int
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/it_defs.h audacious-plugins-2.5.4/src/modplug/it_defs.h
+--- audacious-plugins-2.5.4-orig/src/modplug/it_defs.h	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/it_defs.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,135 +0,0 @@
+-#ifndef _ITDEFS_H_
+-#define _ITDEFS_H_
+-
+-#pragma pack(1)
+-
+-typedef struct tagITFILEHEADER
+-{
+-	DWORD id;			// 0x4D504D49
+-	CHAR songname[26];
+-	BYTE hilight_minor;
+-	BYTE hilight_major;
+-	WORD ordnum;
+-	WORD insnum;
+-	WORD smpnum;
+-	WORD patnum;
+-	WORD cwtv;
+-	WORD cmwt;
+-	WORD flags;
+-	WORD special;
+-	BYTE globalvol;
+-	BYTE mv;
+-	BYTE speed;
+-	BYTE tempo;
+-	BYTE sep;
+-	BYTE pwd;
+-	WORD msglength;
+-	DWORD msgoffset;
+-	DWORD reserved2;
+-	BYTE chnpan[64];
+-	BYTE chnvol[64];
+-} ITFILEHEADER;
+-
+-
+-typedef struct tagITENVELOPE
+-{
+-	BYTE flags;
+-	BYTE num;
+-	BYTE lpb;
+-	BYTE lpe;
+-	BYTE slb;
+-	BYTE sle;
+-	BYTE data[25*3];
+-	BYTE reserved;
+-} ITENVELOPE;
+-
+-// Old Impulse Instrument Format (cmwt < 0x200)
+-typedef struct tagITOLDINSTRUMENT
+-{
+-	DWORD id;			// IMPI = 0x49504D49
+-	CHAR filename[12];	// DOS file name
+-	BYTE zero;
+-	BYTE flags;
+-	BYTE vls;
+-	BYTE vle;
+-	BYTE sls;
+-	BYTE sle;
+-	WORD reserved1;
+-	WORD fadeout;
+-	BYTE nna;
+-	BYTE dnc;
+-	WORD trkvers;
+-	BYTE nos;
+-	BYTE reserved2;
+-	CHAR name[26];
+-	WORD reserved3[3];
+-	BYTE keyboard[240];
+-	BYTE volenv[200];
+-	BYTE nodes[50];
+-} ITOLDINSTRUMENT;
+-
+-
+-// Impulse Instrument Format
+-typedef struct tagITINSTRUMENT
+-{
+-	DWORD id;
+-	CHAR filename[12];
+-	BYTE zero;
+-	BYTE nna;
+-	BYTE dct;
+-	BYTE dca;
+-	WORD fadeout;
+-	signed char pps;
+-	BYTE ppc;
+-	BYTE gbv;
+-	BYTE dfp;
+-	BYTE rv;
+-	BYTE rp;
+-	WORD trkvers;
+-	BYTE nos;
+-	BYTE reserved1;
+-	CHAR name[26];
+-	BYTE ifc;
+-	BYTE ifr;
+-	BYTE mch;
+-	BYTE mpr;
+-	WORD mbank;
+-	BYTE keyboard[240];
+-	ITENVELOPE volenv;
+-	ITENVELOPE panenv;
+-	ITENVELOPE pitchenv;
+-	BYTE dummy[4]; // was 7, but IT v2.17 saves 554 bytes
+-} ITINSTRUMENT;
+-
+-
+-// IT Sample Format
+-typedef struct ITSAMPLESTRUCT
+-{
+-	DWORD id;		// 0x53504D49
+-	CHAR filename[12];
+-	BYTE zero;
+-	BYTE gvl;
+-	BYTE flags;
+-	BYTE vol;
+-	CHAR name[26];
+-	BYTE cvt;
+-	BYTE dfp;
+-	DWORD length;
+-	DWORD loopbegin;
+-	DWORD loopend;
+-	DWORD C5Speed;
+-	DWORD susloopbegin;
+-	DWORD susloopend;
+-	DWORD samplepointer;
+-	BYTE vis;
+-	BYTE vid;
+-	BYTE vir;
+-	BYTE vit;
+-} ITSAMPLESTRUCT;
+-
+-#pragma pack()
+-
+-extern BYTE autovibit2xm[8];
+-extern BYTE autovibxm2it[8];
+-
+-#endif
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_669.cxx audacious-plugins-2.5.4/src/modplug/load_669.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_669.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_669.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,193 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>,
+- *          Adam Goode       <adam at evdebs.org> (endian and char fixes for PPC)
+-*/
+-
+-////////////////////////////////////////////////////////////
+-// 669 Composer / UNIS 669 module loader
+-////////////////////////////////////////////////////////////
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#pragma warning(disable:4244)
+-
+-typedef struct tagFILEHEADER669
+-{
+-	WORD sig;				// 'if' or 'JN'
+-        signed char songmessage[108];	// Song Message
+-	BYTE samples;			// number of samples (1-64)
+-	BYTE patterns;			// number of patterns (1-128)
+-	BYTE restartpos;
+-	BYTE orders[128];
+-	BYTE tempolist[128];
+-	BYTE breaks[128];
+-} FILEHEADER669;
+-
+-
+-typedef struct tagSAMPLE669
+-{
+-	BYTE filename[13];
+-	BYTE length[4];	// when will somebody think about DWORD align ???
+-	BYTE loopstart[4];
+-	BYTE loopend[4];
+-} SAMPLE669;
+-
+-DWORD lengthArrayToDWORD(const BYTE length[4]) {
+-	DWORD len = (length[3] << 24) +
+-		(length[2] << 16) +
+-		(length[1] << 8) +
+-		(length[0]);
+-
+-	return(len);
+-}
+-
+-
+-BOOL CSoundFile::Read669(const BYTE *lpStream, DWORD dwMemLength)
+-//---------------------------------------------------------------
+-{
+-	const FILEHEADER669 *pfh = (const FILEHEADER669 *)lpStream;
+-	const SAMPLE669 *psmp = (const SAMPLE669 *)(lpStream + 0x1F1);
+-	DWORD dwMemPos = 0;
+-
+-	if ((!lpStream) || (dwMemLength < sizeof(FILEHEADER669))) return FALSE;
+-	if ((bswapLE16(pfh->sig) != 0x6669) && (bswapLE16(pfh->sig) != 0x4E4A)) return FALSE;
+-	if ((!pfh->samples) || (pfh->samples > 64) || (pfh->restartpos >= 128)
+-	 || (!pfh->patterns) || (pfh->patterns > 128)) return FALSE;
+-	DWORD dontfuckwithme = 0x1F1 + pfh->samples * sizeof(SAMPLE669) + pfh->patterns * 0x600;
+-	if (dontfuckwithme > dwMemLength) return FALSE;
+-	for (UINT ichk=0; ichk<pfh->samples; ichk++)
+-	{
+-		DWORD len = lengthArrayToDWORD(psmp[ichk].length);
+-		dontfuckwithme += len;
+-	}
+-	if (dontfuckwithme > dwMemLength) return FALSE;
+-	// That should be enough checking: this must be a 669 module.
+-	m_nType = MOD_TYPE_669;
+-	m_dwSongFlags |= SONG_LINEARSLIDES;
+-	m_nMinPeriod = 28 << 2;
+-	m_nMaxPeriod = 1712 << 3;
+-	m_nDefaultTempo = 125;
+-	m_nDefaultSpeed = 6;
+-	m_nChannels = 8;
+-	memcpy(m_szNames[0], pfh->songmessage, 16);
+-	m_nSamples = pfh->samples;
+-	for (UINT nins=1; nins<=m_nSamples; nins++, psmp++)
+-	{
+-		DWORD len = lengthArrayToDWORD(psmp->length);
+-		DWORD loopstart = lengthArrayToDWORD(psmp->loopstart);
+-		DWORD loopend = lengthArrayToDWORD(psmp->loopend);
+-		if (len > MAX_SAMPLE_LENGTH) len = MAX_SAMPLE_LENGTH;
+-		if ((loopend > len) && (!loopstart)) loopend = 0;
+-		if (loopend > len) loopend = len;
+-		if (loopstart + 4 >= loopend) loopstart = loopend = 0;
+-		Ins[nins].nLength = len;
+-		Ins[nins].nLoopStart = loopstart;
+-		Ins[nins].nLoopEnd = loopend;
+-		if (loopend) Ins[nins].uFlags |= CHN_LOOP;
+-		memcpy(m_szNames[nins], psmp->filename, 13);
+-		Ins[nins].nVolume = 256;
+-		Ins[nins].nGlobalVol = 64;
+-		Ins[nins].nPan = 128;
+-	}
+-	// Song Message
+-	m_lpszSongComments = new char[109];
+-	memcpy(m_lpszSongComments, pfh->songmessage, 108);
+-	m_lpszSongComments[108] = 0;
+-	// Reading Orders
+-	memcpy(Order, pfh->orders, 128);
+-	m_nRestartPos = pfh->restartpos;
+-	if (Order[m_nRestartPos] >= pfh->patterns) m_nRestartPos = 0;
+-	// Reading Pattern Break Locations
+-	for (UINT npan=0; npan<8; npan++)
+-	{
+-		ChnSettings[npan].nPan = (npan & 1) ? 0x30 : 0xD0;
+-		ChnSettings[npan].nVolume = 64;
+-	}
+-	// Reading Patterns
+-	dwMemPos = 0x1F1 + pfh->samples * 25;
+-	for (UINT npat=0; npat<pfh->patterns; npat++)
+-	{
+-		Patterns[npat] = AllocatePattern(64, m_nChannels);
+-		if (!Patterns[npat]) break;
+-		PatternSize[npat] = 64;
+-		MODCOMMAND *m = Patterns[npat];
+-		const BYTE *p = lpStream + dwMemPos;
+-		for (UINT row=0; row<64; row++)
+-		{
+-			MODCOMMAND *mspeed = m;
+-			if ((row == pfh->breaks[npat]) && (row != 63))
+-			{
+-				for (UINT i=0; i<8; i++)
+-				{
+-					m[i].command = CMD_PATTERNBREAK;
+-					m[i].param = 0;
+-				}
+-			}
+-			for (UINT n=0; n<8; n++, m++, p+=3)
+-			{
+-				UINT note = p[0] >> 2;
+-				UINT instr = ((p[0] & 0x03) << 4) | (p[1] >> 4);
+-				UINT vol = p[1] & 0x0F;
+-				if (p[0] < 0xFE)
+-				{
+-					m->note = note + 37;
+-					m->instr = instr + 1;
+-				}
+-				if (p[0] <= 0xFE)
+-				{
+-					m->volcmd = VOLCMD_VOLUME;
+-					m->vol = (vol << 2) + 2;
+-				}
+-				if (p[2] != 0xFF)
+-				{
+-					UINT command = p[2] >> 4;
+-					UINT param = p[2] & 0x0F;
+-					switch(command)
+-					{
+-					case 0x00:	command = CMD_PORTAMENTOUP; break;
+-					case 0x01:	command = CMD_PORTAMENTODOWN; break;
+-					case 0x02:	command = CMD_TONEPORTAMENTO; break;
+-					case 0x03:	command = CMD_MODCMDEX; param |= 0x50; break;
+-					case 0x04:	command = CMD_VIBRATO; param |= 0x40; break;
+-					case 0x05:	if (param) command = CMD_SPEED; else command = 0; param += 2; break;
+-					case 0x06:	if (param == 0) { command = CMD_PANNINGSLIDE; param = 0xFE; } else
+-								if (param == 1) { command = CMD_PANNINGSLIDE; param = 0xEF; } else
+-								command = 0;
+-								break;
+-					default:	command = 0;
+-					}
+-					if (command)
+-					{
+-						if (command == CMD_SPEED) mspeed = NULL;
+-						m->command = command;
+-						m->param = param;
+-					}
+-				}
+-			}
+-			if ((!row) && (mspeed))
+-			{
+-				for (UINT i=0; i<8; i++) if (!mspeed[i].command)
+-				{
+-					mspeed[i].command = CMD_SPEED;
+-					mspeed[i].param = pfh->tempolist[npat] + 2;
+-					break;
+-				}
+-			}
+-		}
+-		dwMemPos += 0x600;
+-	}
+-	// Reading Samples
+-	for (UINT n=1; n<=m_nSamples; n++)
+-	{
+-		UINT len = Ins[n].nLength;
+-		if (dwMemPos >= dwMemLength) break;
+-		if (len > 4) ReadSample(&Ins[n], RS_PCM8U, (LPSTR)(lpStream+dwMemPos), dwMemLength - dwMemPos);
+-		dwMemPos += len;
+-	}
+-	return TRUE;
+-}
+-
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_amf.cxx audacious-plugins-2.5.4/src/modplug/load_amf.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_amf.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_amf.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,422 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-///////////////////////////////////////////////////
+-//
+-// AMF module loader
+-//
+-// There is 2 types of AMF files:
+-// - ASYLUM Music Format
+-// - Advanced Music Format(DSM)
+-//
+-///////////////////////////////////////////////////
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#define AMFLOG
+-
+-//#pragma warning(disable:4244)
+-
+-#pragma pack(1)
+-
+-typedef struct _AMFFILEHEADER
+-{
+-	UCHAR szAMF[3];
+-	UCHAR version;
+-	CHAR title[32];
+-	UCHAR numsamples;
+-	UCHAR numorders;
+-	USHORT numtracks;
+-	UCHAR numchannels;
+-} AMFFILEHEADER;
+-
+-typedef struct _AMFSAMPLE
+-{
+-	UCHAR type;
+-	CHAR  samplename[32];
+-	CHAR  filename[13];
+-	ULONG offset;
+-	ULONG length;
+-	USHORT c2spd;
+-	UCHAR volume;
+-} AMFSAMPLE;
+-
+-
+-#pragma pack()
+-
+-
+-#ifdef AMFLOG
+-extern void Log(LPCSTR, ...);
+-#endif
+-
+-VOID AMF_Unpack(MODCOMMAND *pPat, const BYTE *pTrack, UINT nRows, UINT nChannels)
+-//-------------------------------------------------------------------------------
+-{
+-	UINT lastinstr = 0;
+-	UINT nTrkSize = bswapLE16(*(USHORT *)pTrack);
+-	nTrkSize += (UINT)pTrack[2] << 16;
+-	pTrack += 3;
+-	while (nTrkSize--)
+-	{
+-		UINT row = pTrack[0];
+-		UINT cmd = pTrack[1];
+-		UINT arg = pTrack[2];
+-		if (row >= nRows) break;
+-		MODCOMMAND *m = pPat + row * nChannels;
+-		if (cmd < 0x7F) // note+vol
+-		{
+-			m->note = cmd+1;
+-			if (!m->instr) m->instr = lastinstr;
+-			m->volcmd = VOLCMD_VOLUME;
+-			m->vol = arg;
+-		} else
+-		if (cmd == 0x7F) // duplicate row
+-		{
+-			signed char rdelta = (signed char)arg;
+-			int rowsrc = (int)row + (int)rdelta;
+-			if ((rowsrc >= 0) && (rowsrc < (int)nRows)) memcpy(m, &pPat[rowsrc*nChannels],sizeof(pPat[rowsrc*nChannels]));
+-		} else
+-		if (cmd == 0x80) // instrument
+-		{
+-			m->instr = arg+1;
+-			lastinstr = m->instr;
+-		} else
+-		if (cmd == 0x83) // volume
+-		{
+-			m->volcmd = VOLCMD_VOLUME;
+-			m->vol = arg;
+-		} else
+-		// effect
+-		{
+-			UINT command = cmd & 0x7F;
+-			UINT param = arg;
+-			switch(command)
+-			{
+-			// 0x01: Set Speed
+-			case 0x01:	command = CMD_SPEED; break;
+-			// 0x02: Volume Slide
+-			// 0x0A: Tone Porta + Vol Slide
+-			// 0x0B: Vibrato + Vol Slide
+-			case 0x02:	command = CMD_VOLUMESLIDE;
+-			case 0x0A:	if (command == 0x0A) command = CMD_TONEPORTAVOL;
+-			case 0x0B:	if (command == 0x0B) command = CMD_VIBRATOVOL;
+-						if (param & 0x80) param = (-(signed char)param)&0x0F;
+-						else param = (param&0x0F)<<4;
+-						break;
+-			// 0x04: Porta Up/Down
+-			case 0x04:	if (param & 0x80) { command = CMD_PORTAMENTOUP; param = (-(signed char)param)&0x7F; }
+-						else { command = CMD_PORTAMENTODOWN; } break;
+-			// 0x06: Tone Portamento
+-			case 0x06:	command = CMD_TONEPORTAMENTO; break;
+-			// 0x07: Tremor
+-			case 0x07:	command = CMD_TREMOR; break;
+-			// 0x08: Arpeggio
+-			case 0x08:	command = CMD_ARPEGGIO; break;
+-			// 0x09: Vibrato
+-			case 0x09:	command = CMD_VIBRATO; break;
+-			// 0x0C: Pattern Break
+-			case 0x0C:	command = CMD_PATTERNBREAK; break;
+-			// 0x0D: Position Jump
+-			case 0x0D:	command = CMD_POSITIONJUMP; break;
+-			// 0x0F: Retrig
+-			case 0x0F:	command = CMD_RETRIG; break;
+-			// 0x10: Offset
+-			case 0x10:	command = CMD_OFFSET; break;
+-			// 0x11: Fine Volume Slide
+-			case 0x11:	if (param) { command = CMD_VOLUMESLIDE;
+-							if (param & 0x80) param = 0xF0|((-(signed char)param)&0x0F);
+-							else param = 0x0F|((param&0x0F)<<4);
+-						} else command = 0; break;
+-			// 0x12: Fine Portamento
+-			// 0x16: Extra Fine Portamento
+-			case 0x12:
+-			case 0x16:	if (param) { int mask = (command == 0x16) ? 0xE0 : 0xF0;
+-							command = (param & 0x80) ? CMD_PORTAMENTOUP : CMD_PORTAMENTODOWN;
+-							if (param & 0x80) param = mask|((-(signed char)param)&0x0F);
+-							else param |= mask;
+-						} else command = 0; break;
+-			// 0x13: Note Delay
+-			case 0x13:	command = CMD_S3MCMDEX; param = 0xD0|(param & 0x0F); break;
+-			// 0x14: Note Cut
+-			case 0x14:	command = CMD_S3MCMDEX; param = 0xC0|(param & 0x0F); break;
+-			// 0x15: Set Tempo
+-			case 0x15:	command = CMD_TEMPO; break;
+-			// 0x17: Panning
+-			case 0x17:	param = (param+64)&0x7F;
+-						if (m->command) { if (!m->volcmd) { m->volcmd = VOLCMD_PANNING;  m->vol = param/2; } command = 0; }
+-						else { command = CMD_PANNING8; }
+-			// Unknown effects
+-			default:	command = param = 0;
+-			}
+-			if (command)
+-			{
+-				m->command = command;
+-				m->param = param;
+-			}
+-		}
+-		pTrack += 3;
+-	}
+-}
+-
+-
+-
+-BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, const DWORD dwMemLength)
+-//-----------------------------------------------------------
+-{
+-	const AMFFILEHEADER *pfh = (AMFFILEHEADER *)lpStream;
+-	DWORD dwMemPos;
+-	
+-	if ((!lpStream) || (dwMemLength < 2048)) return FALSE;
+-	if ((!strncmp((LPCTSTR)lpStream, "ASYLUM Music Format V1.0", 25)) && (dwMemLength > 4096))
+-	{
+-		UINT numorders, numpats, numsamples;
+-
+-		dwMemPos = 32;
+-		numpats = lpStream[dwMemPos+3];
+-		numorders = lpStream[dwMemPos+4];
+-		numsamples = 64;
+-		dwMemPos += 6;
+-		if ((!numpats) || (numpats > MAX_PATTERNS) || (!numorders)
+-		 || (numpats*64*32 + 294 + 37*64 >= dwMemLength)) return FALSE;
+-		m_nType = MOD_TYPE_AMF0;
+-		m_nChannels = 8;
+-		m_nInstruments = 0;
+-		m_nSamples = 31;
+-		m_nDefaultTempo = 125;
+-		m_nDefaultSpeed = 6;
+-		for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
+-		{
+-			Order[iOrd] = (iOrd < numorders) ? lpStream[dwMemPos+iOrd] : 0xFF;
+-		}
+-		dwMemPos = 294; // ???
+-		for (UINT iSmp=0; iSmp<numsamples; iSmp++)
+-		{
+-			MODINSTRUMENT *psmp = &Ins[iSmp+1];
+-			memcpy(m_szNames[iSmp+1], lpStream+dwMemPos, 22);
+-			m_szNames[iSmp+1][21] = '\0';
+-			psmp->nFineTune = MOD2XMFineTune(lpStream[dwMemPos+22]);
+-			psmp->nVolume = lpStream[dwMemPos+23];
+-			psmp->nGlobalVol = 64;
+-			if (psmp->nVolume > 0x40) psmp->nVolume = 0x40;
+-			psmp->nVolume <<= 2;
+-			psmp->nLength = bswapLE32(*((LPDWORD)(lpStream+dwMemPos+25)));
+-			psmp->nLoopStart = bswapLE32(*((LPDWORD)(lpStream+dwMemPos+29)));
+-			psmp->nLoopEnd = psmp->nLoopStart + bswapLE32(*((LPDWORD)(lpStream+dwMemPos+33)));
+-			if ((psmp->nLoopEnd > psmp->nLoopStart) && (psmp->nLoopEnd <= psmp->nLength))
+-			{
+-				psmp->uFlags = CHN_LOOP;
+-			} else
+-			{
+-				psmp->nLoopStart = psmp->nLoopEnd = 0;
+-			}
+-			if ((psmp->nLength) && (iSmp>31)) m_nSamples = iSmp+1;
+-			dwMemPos += 37;
+-		}
+-		for (UINT iPat=0; iPat<numpats; iPat++)
+-		{
+-			MODCOMMAND *p = AllocatePattern(64, m_nChannels);
+-			if (!p) break;
+-			Patterns[iPat] = p;
+-			PatternSize[iPat] = 64;
+-			const UCHAR *pin = lpStream + dwMemPos;
+-			for (UINT i=0; i<8*64; i++)
+-			{
+-				p->note = 0;
+-
+-				if (pin[0])
+-				{
+-					p->note = pin[0] + 13;
+-				}
+-				p->instr = pin[1];
+-				p->command = pin[2];
+-				p->param = pin[3];
+-				if (p->command > 0x0F)
+-				{
+-				#ifdef AMFLOG
+-					Log("0x%02X.0x%02X ?", p->command, p->param);
+-				#endif
+-					p->command = 0;
+-				}
+-				ConvertModCommand(p);
+-				pin += 4;
+-				p++;
+-			}
+-			dwMemPos += 64*32;
+-		}
+-		// Read samples
+-		for (UINT iData=0; iData<m_nSamples; iData++)
+-		{
+-			MODINSTRUMENT *psmp = &Ins[iData+1];
+-			if (psmp->nLength)
+-			{
+-				if (dwMemPos > dwMemLength) return FALSE;
+-				dwMemPos += ReadSample(psmp, RS_PCM8S, (LPCSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos);
+-			}
+-		}
+-		return TRUE;
+-	}
+-	////////////////////////////
+-	// DSM/AMF
+-	USHORT *ptracks[MAX_PATTERNS];
+-	DWORD sampleseekpos[MAX_SAMPLES];
+-
+-	if ((pfh->szAMF[0] != 'A') || (pfh->szAMF[1] != 'M') || (pfh->szAMF[2] != 'F')
+-	 || (pfh->version < 10) || (pfh->version > 14) || (!bswapLE16(pfh->numtracks))
+-	 || (!pfh->numorders) || (pfh->numorders > MAX_PATTERNS)
+-	 || (!pfh->numsamples) || (pfh->numsamples > MAX_SAMPLES)
+-	 || (pfh->numchannels < 4) || (pfh->numchannels > 32))
+-		return FALSE;
+-	memcpy(m_szNames[0], pfh->title, 32);
+-	m_szNames[0][31] = '\0';
+-	dwMemPos = sizeof(AMFFILEHEADER);
+-	m_nType = MOD_TYPE_AMF;
+-	m_nChannels = pfh->numchannels;
+-	m_nSamples = pfh->numsamples;
+-	m_nInstruments = 0;
+-	// Setup Channel Pan Positions
+-	if (pfh->version >= 11)
+-	{
+-		signed char *panpos = (signed char *)(lpStream + dwMemPos);
+-		UINT nchannels = (pfh->version >= 13) ? 32 : 16;
+-		for (UINT i=0; i<nchannels; i++)
+-		{
+-			int pan = (panpos[i] + 64) * 2;
+-			if (pan < 0) pan = 0;
+-			if (pan > 256) { pan = 128; ChnSettings[i].dwFlags |= CHN_SURROUND; }
+-			ChnSettings[i].nPan = pan;
+-		}
+-		dwMemPos += nchannels;
+-	} else
+-	{
+-		for (UINT i=0; i<16; i++)
+-		{
+-			ChnSettings[i].nPan = (lpStream[dwMemPos+i] & 1) ? 0x30 : 0xD0;
+-		}
+-		dwMemPos += 16;
+-	}
+-	// Get Tempo/Speed
+-	m_nDefaultTempo = 125;
+-	m_nDefaultSpeed = 6;
+-	if (pfh->version >= 13)
+-	{
+-		if (lpStream[dwMemPos] >= 32) m_nDefaultTempo = lpStream[dwMemPos];
+-		if (lpStream[dwMemPos+1] <= 32) m_nDefaultSpeed = lpStream[dwMemPos+1];
+-		dwMemPos += 2;
+-	}
+-	// Setup sequence list
+-	for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
+-	{
+-		Order[iOrd] = 0xFF;
+-		if (iOrd < pfh->numorders)
+-		{
+-			Order[iOrd] = iOrd;
+-			PatternSize[iOrd] = 64;
+-			if (pfh->version >= 14)
+-			{
+-				PatternSize[iOrd] = bswapLE16(*(USHORT *)(lpStream+dwMemPos));
+-				dwMemPos += 2;
+-			}
+-			ptracks[iOrd] = (USHORT *)(lpStream+dwMemPos);
+-			dwMemPos += m_nChannels * sizeof(USHORT);
+-		}
+-	}
+-	if (dwMemPos + m_nSamples * (sizeof(AMFSAMPLE)+8) > dwMemLength) return TRUE;
+-	// Read Samples
+-	UINT maxsampleseekpos = 0;
+-	for (UINT iIns=0; iIns<m_nSamples; iIns++)
+-	{
+-		MODINSTRUMENT *pins = &Ins[iIns+1];
+-		AMFSAMPLE *psh = (AMFSAMPLE *)(lpStream + dwMemPos);
+-
+-		dwMemPos += sizeof(AMFSAMPLE);
+-		memcpy(m_szNames[iIns+1], psh->samplename, 32);
+-		m_szNames[iIns+1][31] = '\0';
+-		memcpy(pins->name, psh->filename, 13);
+-		pins->name[12] = '\0';
+-		pins->nLength = bswapLE32(psh->length);
+-		pins->nC4Speed = bswapLE16(psh->c2spd);
+-		pins->nGlobalVol = 64;
+-		pins->nVolume = psh->volume * 4;
+-		if (pfh->version >= 11)
+-		{
+-			pins->nLoopStart = bswapLE32(*(DWORD *)(lpStream+dwMemPos));
+-			pins->nLoopEnd = bswapLE32(*(DWORD *)(lpStream+dwMemPos+4));
+-			dwMemPos += 8;
+-		} else
+-		{
+-			pins->nLoopStart = bswapLE16(*(WORD *)(lpStream+dwMemPos));
+-			pins->nLoopEnd = pins->nLength;
+-			dwMemPos += 2;
+-		}
+-		sampleseekpos[iIns] = 0;
+-		if ((psh->type) && (bswapLE32(psh->offset) < dwMemLength-1))
+-		{
+-			sampleseekpos[iIns] = bswapLE32(psh->offset);
+-			if (bswapLE32(psh->offset) > maxsampleseekpos) 
+-				maxsampleseekpos = bswapLE32(psh->offset);
+-			if ((pins->nLoopEnd > pins->nLoopStart + 2)
+-			 && (pins->nLoopEnd <= pins->nLength)) pins->uFlags |= CHN_LOOP;
+-		}
+-	}
+-	// Read Track Mapping Table
+-	USHORT *pTrackMap = (USHORT *)(lpStream+dwMemPos);
+-	UINT realtrackcnt = 0;
+-	dwMemPos += pfh->numtracks * sizeof(USHORT);
+-	for (UINT iTrkMap=0; iTrkMap<pfh->numtracks; iTrkMap++)
+-	{
+-		if (realtrackcnt < pTrackMap[iTrkMap]) realtrackcnt = pTrackMap[iTrkMap];
+-	}
+-	// Store tracks positions
+-	BYTE **pTrackData = new BYTE *[realtrackcnt];
+-	memset(pTrackData, 0, sizeof(pTrackData));
+-	for (UINT iTrack=0; iTrack<realtrackcnt; iTrack++) if (dwMemPos + 3 <= dwMemLength)
+-	{
+-		UINT nTrkSize = bswapLE16(*(USHORT *)(lpStream+dwMemPos));
+-		nTrkSize += (UINT)lpStream[dwMemPos+2] << 16;
+-		if (dwMemPos + nTrkSize * 3 + 3 <= dwMemLength)
+-		{
+-			pTrackData[iTrack] = (BYTE *)(lpStream + dwMemPos);
+-		}
+-		dwMemPos += nTrkSize * 3 + 3;
+-	}
+-	// Create the patterns from the list of tracks
+-	for (UINT iPat=0; iPat<pfh->numorders; iPat++)
+-	{
+-		MODCOMMAND *p = AllocatePattern(PatternSize[iPat], m_nChannels);
+-		if (!p) break;
+-		Patterns[iPat] = p;
+-		for (UINT iChn=0; iChn<m_nChannels; iChn++)
+-		{
+-			UINT nTrack = bswapLE16(ptracks[iPat][iChn]);
+-			if ((nTrack) && (nTrack <= pfh->numtracks))
+-			{
+-				UINT realtrk = bswapLE16(pTrackMap[nTrack-1]);
+-				if (realtrk)
+-				{
+-					realtrk--;
+-					if ((realtrk < realtrackcnt) && (pTrackData[realtrk]))
+-					{
+-						AMF_Unpack(p+iChn, pTrackData[realtrk], PatternSize[iPat], m_nChannels);
+-					}
+-				}
+-			}
+-		}
+-	}
+-	delete[] pTrackData;
+-	// Read Sample Data
+-	for (UINT iSeek=1; iSeek<=maxsampleseekpos; iSeek++)
+-	{
+-		if (dwMemPos >= dwMemLength) break;
+-		for (UINT iSmp=0; iSmp<m_nSamples; iSmp++) if (iSeek == sampleseekpos[iSmp])
+-		{
+-			MODINSTRUMENT *pins = &Ins[iSmp+1];
+-			dwMemPos += ReadSample(pins, RS_PCM8U, (LPCSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos);
+-			break;
+-		}
+-	}
+-	return TRUE;
+-}
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_ams.cxx audacious-plugins-2.5.4/src/modplug/load_ams.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_ams.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_ams.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,629 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-//////////////////////////////////////////////
+-// AMS module loader                        //
+-//////////////////////////////////////////////
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#pragma warning(disable:4244)
+-
+-#pragma pack(1)
+-
+-typedef struct AMSFILEHEADER
+-{
+-	char szHeader[7];	// "Extreme"   // changed from CHAR
+-	BYTE verlo, verhi;	// 0x??,0x01
+-	BYTE chncfg;
+-	BYTE samples;
+-	WORD patterns;
+-	WORD orders;
+-	BYTE vmidi;
+-	WORD extra;
+-} AMSFILEHEADER;
+-
+-typedef struct AMSSAMPLEHEADER
+-{
+-	DWORD length;
+-	DWORD loopstart;
+-	DWORD loopend;
+-	BYTE finetune_and_pan;
+-	WORD samplerate;	// C-2 = 8363
+-	BYTE volume;		// 0-127
+-	BYTE infobyte;
+-} AMSSAMPLEHEADER;
+-
+-
+-#pragma pack()
+-
+-
+-
+-BOOL CSoundFile::ReadAMS(LPCBYTE lpStream, DWORD dwMemLength)
+-//-----------------------------------------------------------
+-{
+-	AMSFILEHEADER *pfh = (AMSFILEHEADER *)lpStream;
+-	DWORD dwMemPos;
+-	UINT tmp, tmp2;
+-	
+-	if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
+-	if ((pfh->verhi != 0x01) || (strncmp(pfh->szHeader, "Extreme", 7))
+-	 || (!pfh->patterns) || (!pfh->orders) || (!pfh->samples) || (pfh->samples > MAX_SAMPLES)
+-	 || (pfh->patterns > MAX_PATTERNS) || (pfh->orders > MAX_ORDERS))
+-	{
+-		return ReadAMS2(lpStream, dwMemLength);
+-	}
+-	dwMemPos = sizeof(AMSFILEHEADER) + pfh->extra;
+-	if (dwMemPos + pfh->samples * sizeof(AMSSAMPLEHEADER) + 256 >= dwMemLength) return FALSE;
+-	m_nType = MOD_TYPE_AMS;
+-	m_nInstruments = 0;
+-	m_nChannels = (pfh->chncfg & 0x1F) + 1;
+-	m_nSamples = pfh->samples;
+-	for (UINT nSmp=1; nSmp<=m_nSamples; nSmp++, dwMemPos += sizeof(AMSSAMPLEHEADER))
+-	{
+-		AMSSAMPLEHEADER *psh = (AMSSAMPLEHEADER *)(lpStream + dwMemPos);
+-		MODINSTRUMENT *pins = &Ins[nSmp];
+-		pins->nLength = psh->length;
+-		pins->nLoopStart = psh->loopstart;
+-		pins->nLoopEnd = psh->loopend;
+-		pins->nGlobalVol = 64;
+-		pins->nVolume = psh->volume << 1;
+-		pins->nC4Speed = psh->samplerate;
+-		pins->nPan = (psh->finetune_and_pan & 0xF0);
+-		if (pins->nPan < 0x80) pins->nPan += 0x10;
+-		pins->nFineTune = MOD2XMFineTune(psh->finetune_and_pan & 0x0F);
+-		pins->uFlags = (psh->infobyte & 0x80) ? CHN_16BIT : 0;
+-		if ((pins->nLoopEnd <= pins->nLength) && (pins->nLoopStart+4 <= pins->nLoopEnd)) pins->uFlags |= CHN_LOOP;
+-	}
+-	// Read Song Name
+-	tmp = lpStream[dwMemPos++];
+-	if (dwMemPos + tmp + 1 >= dwMemLength) return TRUE;
+-	tmp2 = (tmp < 32) ? tmp : 31;
+-	if (tmp2) memcpy(m_szNames[0], lpStream+dwMemPos, tmp2);
+-	m_szNames[0][tmp2] = 0;
+-	dwMemPos += tmp;
+-	// Read sample names
+-	for (UINT sNam=1; sNam<=m_nSamples; sNam++)
+-	{
+-		if (dwMemPos + 32 >= dwMemLength) return TRUE;
+-		tmp = lpStream[dwMemPos++];
+-		tmp2 = (tmp < 32) ? tmp : 31;
+-		if (tmp2) memcpy(m_szNames[sNam], lpStream+dwMemPos, tmp2);
+-		dwMemPos += tmp;
+-	}
+-	// Skip Channel names
+-	for (UINT cNam=0; cNam<m_nChannels; cNam++)
+-	{
+-		if (dwMemPos + 32 >= dwMemLength) return TRUE;
+-		tmp = lpStream[dwMemPos++];
+-		dwMemPos += tmp;
+-	}
+-	// Read Pattern Names
+-	m_lpszPatternNames = new char[pfh->patterns * 32];  // changed from CHAR
+-	if (!m_lpszPatternNames) return TRUE;
+-	m_nPatternNames = pfh->patterns;
+-	memset(m_lpszPatternNames, 0, m_nPatternNames * 32);
+-	for (UINT pNam=0; pNam < m_nPatternNames; pNam++)
+-	{
+-		if (dwMemPos + 32 >= dwMemLength) return TRUE;
+-		tmp = lpStream[dwMemPos++];
+-		tmp2 = (tmp < 32) ? tmp : 31;
+-		if (tmp2) memcpy(m_lpszPatternNames+pNam*32, lpStream+dwMemPos, tmp2);
+-		dwMemPos += tmp;
+-	}
+-	// Read Song Comments
+-	tmp = *((WORD *)(lpStream+dwMemPos));
+-	dwMemPos += 2;
+-	if (dwMemPos + tmp >= dwMemLength) return TRUE;
+-	if (tmp)
+-	{
+-		m_lpszSongComments = new char[tmp+1];  // changed from CHAR
+-		if (!m_lpszSongComments) return TRUE;
+-		memset(m_lpszSongComments, 0, tmp+1);
+-		memcpy(m_lpszSongComments, lpStream + dwMemPos, tmp);
+-		dwMemPos += tmp;
+-	}
+-	// Read Order List
+-	for (UINT iOrd=0; iOrd<pfh->orders; iOrd++, dwMemPos += 2)
+-	{
+-		UINT n = *((WORD *)(lpStream+dwMemPos));
+-		Order[iOrd] = (BYTE)n;
+-	}
+-	// Read Patterns
+-	for (UINT iPat=0; iPat<pfh->patterns; iPat++)
+-	{
+-		if (dwMemPos + 4 >= dwMemLength) return TRUE;
+-		UINT len = *((DWORD *)(lpStream + dwMemPos));
+-		dwMemPos += 4;
+-		if ((len >= dwMemLength) || (dwMemPos + len > dwMemLength)) return TRUE;
+-		PatternSize[iPat] = 64;
+-		PatternAllocSize[iPat] = 64;
+-		MODCOMMAND *m = AllocatePattern(PatternSize[iPat], m_nChannels);
+-		if (!m) return TRUE;
+-		Patterns[iPat] = m;
+-		const BYTE *p = lpStream + dwMemPos;
+-		UINT row = 0, i = 0;
+-		while ((row < PatternSize[iPat]) && (i+2 < len))
+-		{
+-			BYTE b0 = p[i++];
+-			BYTE b1 = p[i++];
+-			BYTE b2 = 0;
+-			UINT ch = b0 & 0x3F;
+-			// Note+Instr
+-			if (!(b0 & 0x40))
+-			{
+-				b2 = p[i++];
+-				if (ch < m_nChannels)
+-				{
+-					if (b1 & 0x7F) m[ch].note = (b1 & 0x7F) + 25;
+-					m[ch].instr = b2;
+-				}
+-				if (b1 & 0x80)
+-				{
+-					b0 |= 0x40;
+-					b1 = p[i++];
+-				}
+-			}
+-			// Effect
+-			if (b0 & 0x40)
+-			{
+-			anothercommand:
+-				if (b1 & 0x40)
+-				{
+-					if (ch < m_nChannels)
+-					{
+-						m[ch].volcmd = VOLCMD_VOLUME;
+-						m[ch].vol = b1 & 0x3F;
+-					}
+-				} else
+-				{
+-					b2 = p[i++];
+-					if (ch < m_nChannels)
+-					{
+-						UINT cmd = b1 & 0x3F;
+-						if (cmd == 0x0C)
+-						{
+-							m[ch].volcmd = VOLCMD_VOLUME;
+-							m[ch].vol = b2 >> 1;
+-						} else
+-						if (cmd == 0x0E)
+-						{
+-							if (!m[ch].command)
+-							{
+-								UINT command = CMD_S3MCMDEX;
+-								UINT param = b2;
+-								switch(param & 0xF0)
+-								{
+-								case 0x00:	if (param & 0x08) { param &= 0x07; param |= 0x90; } else {command=param=0;} break;
+-								case 0x10:	command = CMD_PORTAMENTOUP; param |= 0xF0; break;
+-								case 0x20:	command = CMD_PORTAMENTODOWN; param |= 0xF0; break;
+-								case 0x30:	param = (param & 0x0F) | 0x10; break;
+-								case 0x40:	param = (param & 0x0F) | 0x30; break;
+-								case 0x50:	param = (param & 0x0F) | 0x20; break;
+-								case 0x60:	param = (param & 0x0F) | 0xB0; break;
+-								case 0x70:	param = (param & 0x0F) | 0x40; break;
+-								case 0x90:	command = CMD_RETRIG; param &= 0x0F; break;
+-								case 0xA0:	if (param & 0x0F) { command = CMD_VOLUMESLIDE; param = (param << 4) | 0x0F; } else command=param=0; break;
+-								case 0xB0:	if (param & 0x0F) { command = CMD_VOLUMESLIDE; param |= 0xF0; } else command=param=0; break;
+-								}
+-								m[ch].command = command;
+-								m[ch].param = param;
+-							}
+-						} else
+-						{
+-							m[ch].command = cmd;
+-							m[ch].param = b2;
+-							ConvertModCommand(&m[ch]);
+-						}
+-					}
+-				}
+-				if (b1 & 0x80)
+-				{
+-					b1 = p[i++];
+-					if (i <= len) goto anothercommand;
+-				}
+-			}
+-			if (b0 & 0x80)
+-			{
+-				row++;
+-				m += m_nChannels;
+-			}
+-		}
+-		dwMemPos += len;
+-	}
+-	// Read Samples
+-	for (UINT iSmp=1; iSmp<=m_nSamples; iSmp++) if (Ins[iSmp].nLength)
+-	{
+-		if (dwMemPos >= dwMemLength - 9) return TRUE;
+-		UINT flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_AMS16 : RS_AMS8;
+-		dwMemPos += ReadSample(&Ins[iSmp], flags, (LPSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos);
+-	}
+-	return TRUE;
+-}
+-
+-
+-/////////////////////////////////////////////////////////////////////
+-// AMS 2.2 loader
+-
+-#pragma pack(1)
+-
+-typedef struct AMS2FILEHEADER
+-{
+-	DWORD dwHdr1;		// AMShdr
+-	WORD wHdr2;
+-	BYTE b1A;			// 0x1A
+-	BYTE titlelen;		// 30-bytes max
+-	CHAR szTitle[30];	// [titlelen]
+-} AMS2FILEHEADER;
+-
+-typedef struct AMS2SONGHEADER
+-{
+-	WORD version;
+-	BYTE instruments;
+-	WORD patterns;
+-	WORD orders;
+-	WORD bpm;
+-	BYTE speed;
+-	BYTE channels;
+-	BYTE commands;
+-	BYTE rows;
+-	WORD flags;
+-} AMS2SONGHEADER;
+-
+-typedef struct AMS2INSTRUMENT
+-{
+-	BYTE samples;
+-	BYTE notemap[120];
+-} AMS2INSTRUMENT;
+-
+-typedef struct AMS2ENVELOPE
+-{
+-	BYTE speed;
+-	BYTE sustain;
+-	BYTE loopbegin;
+-	BYTE loopend;
+-	BYTE points;
+-	BYTE info[3];
+-} AMS2ENVELOPE;
+-
+-typedef struct AMS2SAMPLE
+-{
+-	DWORD length;
+-	DWORD loopstart;
+-	DWORD loopend;
+-	WORD frequency;
+-	BYTE finetune;
+-	WORD c4speed;
+-	CHAR transpose;
+-	BYTE volume;
+-	BYTE flags;
+-} AMS2SAMPLE;
+-
+-
+-#pragma pack()
+-
+-
+-BOOL CSoundFile::ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength)
+-//------------------------------------------------------------
+-{
+-	AMS2FILEHEADER *pfh = (AMS2FILEHEADER *)lpStream;
+-	AMS2SONGHEADER *psh;
+-	DWORD dwMemPos;
+-	BYTE smpmap[16];
+-	BYTE packedsamples[MAX_SAMPLES];
+-
+-	if ((pfh->dwHdr1 != 0x68534D41) || (pfh->wHdr2 != 0x7264)
+-	 || (pfh->b1A != 0x1A) || (pfh->titlelen > 30)) return FALSE;
+-	dwMemPos = pfh->titlelen + 8;
+-	psh = (AMS2SONGHEADER *)(lpStream + dwMemPos);
+-	if (((psh->version & 0xFF00) != 0x0200) || (!psh->instruments)
+-	 || (psh->instruments > MAX_INSTRUMENTS) || (!psh->patterns) || (!psh->orders)) return FALSE;
+-	dwMemPos += sizeof(AMS2SONGHEADER);
+-	if (pfh->titlelen)
+-	{
+-		memcpy(m_szNames, pfh->szTitle, pfh->titlelen);
+-		m_szNames[0][pfh->titlelen] = 0;
+-	}
+-	m_nType = MOD_TYPE_AMS;
+-	m_nChannels = 32;
+-	m_nDefaultTempo = psh->bpm >> 8;
+-	m_nDefaultSpeed = psh->speed;
+-	m_nInstruments = psh->instruments;
+-	m_nSamples = 0;
+-	m_dwSongFlags |= SONG_INSTRUMENTMODE;
+-	if (psh->flags & 0x40) m_dwSongFlags |= SONG_LINEARSLIDES;
+-	for (UINT nIns=1; nIns<=m_nInstruments; nIns++)
+-	{
+-		UINT insnamelen = lpStream[dwMemPos];
+-		CHAR *pinsname = (CHAR *)(lpStream+dwMemPos+1);
+-		dwMemPos += insnamelen + 1;
+-		AMS2INSTRUMENT *pins = (AMS2INSTRUMENT *)(lpStream + dwMemPos);
+-		dwMemPos += sizeof(AMS2INSTRUMENT);
+-		if (dwMemPos + 1024 >= dwMemLength) return TRUE;
+-		AMS2ENVELOPE *volenv, *panenv, *pitchenv;
+-		volenv = (AMS2ENVELOPE *)(lpStream+dwMemPos);
+-		dwMemPos += 5 + volenv->points*3;
+-		panenv = (AMS2ENVELOPE *)(lpStream+dwMemPos);
+-		dwMemPos += 5 + panenv->points*3;
+-		pitchenv = (AMS2ENVELOPE *)(lpStream+dwMemPos);
+-		dwMemPos += 5 + pitchenv->points*3;
+-		INSTRUMENTHEADER *penv = new INSTRUMENTHEADER;
+-		if (!penv) return TRUE;
+-		memset(smpmap, 0, sizeof(smpmap));
+-		memset(penv, 0, sizeof(INSTRUMENTHEADER));
+-		for (UINT ismpmap=0; ismpmap<pins->samples; ismpmap++)
+-		{
+-			if ((ismpmap >= 16) || (m_nSamples+1 >= MAX_SAMPLES)) break;
+-			m_nSamples++;
+-			smpmap[ismpmap] = m_nSamples;
+-		}
+-		penv->nGlobalVol = 64;
+-		penv->nPan = 128;
+-		penv->nPPC = 60;
+-		Headers[nIns] = penv;
+-		if (insnamelen)
+-		{
+-			if (insnamelen > 31) insnamelen = 31;
+-			memcpy(penv->name, pinsname, insnamelen);
+-			penv->name[insnamelen] = 0;
+-		}
+-		for (UINT inotemap=0; inotemap<120; inotemap++)
+-		{
+-			penv->NoteMap[inotemap] = inotemap+1;
+-			penv->Keyboard[inotemap] = smpmap[pins->notemap[inotemap] & 0x0F];
+-		}
+-		// Volume Envelope
+-		{
+-			UINT pos = 0;
+-			penv->VolEnv.nNodes = (volenv->points > 16) ? 16 : volenv->points;
+-			penv->VolEnv.nSustainStart = penv->VolEnv.nSustainEnd = volenv->sustain;
+-			penv->VolEnv.nLoopStart = volenv->loopbegin;
+-			penv->VolEnv.nLoopEnd = volenv->loopend;
+-			for (int i=0; i<penv->VolEnv.nNodes; i++)
+-			{
+-				penv->VolEnv.Values[i] = (BYTE)((volenv->info[i*3+2] & 0x7F) >> 1);
+-				pos += volenv->info[i*3] + ((volenv->info[i*3+1] & 1) << 8);
+-				penv->VolEnv.Ticks[i] = (WORD)pos;
+-			}
+-		}
+-		penv->nFadeOut = (((lpStream[dwMemPos+2] & 0x0F) << 8) | (lpStream[dwMemPos+1])) << 3;
+-		UINT envflags = lpStream[dwMemPos+3];
+-		if (envflags & 0x01) penv->dwFlags |= ENV_VOLLOOP;
+-		if (envflags & 0x02) penv->dwFlags |= ENV_VOLSUSTAIN;
+-		if (envflags & 0x04) penv->dwFlags |= ENV_VOLUME;
+-		dwMemPos += 5;
+-		// Read Samples
+-		for (UINT ismp=0; ismp<pins->samples; ismp++)
+-		{
+-			MODINSTRUMENT *psmp = ((ismp < 16) && (smpmap[ismp])) ? &Ins[smpmap[ismp]] : NULL;
+-			UINT smpnamelen = lpStream[dwMemPos];
+-			if ((psmp) && (smpnamelen) && (smpnamelen <= 22))
+-			{
+-				memcpy(m_szNames[smpmap[ismp]], lpStream+dwMemPos+1, smpnamelen);
+-			}
+-			dwMemPos += smpnamelen + 1;
+-			if (psmp)
+-			{
+-				AMS2SAMPLE *pams = (AMS2SAMPLE *)(lpStream+dwMemPos);
+-				psmp->nGlobalVol = 64;
+-				psmp->nPan = 128;
+-				psmp->nLength = pams->length;
+-				psmp->nLoopStart = pams->loopstart;
+-				psmp->nLoopEnd = pams->loopend;
+-				psmp->nC4Speed = pams->c4speed;
+-				psmp->RelativeTone = pams->transpose;
+-				psmp->nVolume = pams->volume / 2;
+-				packedsamples[smpmap[ismp]] = pams->flags;
+-				if (pams->flags & 0x04) psmp->uFlags |= CHN_16BIT;
+-				if (pams->flags & 0x08) psmp->uFlags |= CHN_LOOP;
+-				if (pams->flags & 0x10) psmp->uFlags |= CHN_PINGPONGLOOP;
+-			}
+-			dwMemPos += sizeof(AMS2SAMPLE);
+-		}
+-	}
+-	if (dwMemPos + 256 >= dwMemLength) return TRUE;
+-	// Comments
+-	{
+-		UINT composernamelen = lpStream[dwMemPos];
+-		if (composernamelen)
+-		{
+-			m_lpszSongComments = new char[composernamelen+1]; // changed from CHAR
+-			if (m_lpszSongComments)
+-			{
+-				memcpy(m_lpszSongComments, lpStream+dwMemPos+1, composernamelen);
+-				m_lpszSongComments[composernamelen] = 0;
+-			}
+-		}
+-		dwMemPos += composernamelen + 1;
+-		// channel names
+-		for (UINT i=0; i<32; i++)
+-		{
+-			UINT chnnamlen = lpStream[dwMemPos];
+-			if ((chnnamlen) && (chnnamlen < MAX_CHANNELNAME))
+-			{
+-				memcpy(ChnSettings[i].szName, lpStream+dwMemPos+1, chnnamlen);
+-			}
+-			dwMemPos += chnnamlen + 1;
+-			if (dwMemPos + chnnamlen + 256 >= dwMemLength) return TRUE;
+-		}
+-		// packed comments (ignored)
+-		UINT songtextlen = *((LPDWORD)(lpStream+dwMemPos));
+-		dwMemPos += songtextlen;
+-		if (dwMemPos + 256 >= dwMemLength) return TRUE;
+-	}
+-	// Order List
+-	{
+-		for (UINT i=0; i<MAX_ORDERS; i++)
+-		{
+-			Order[i] = 0xFF;
+-			if (dwMemPos + 2 >= dwMemLength) return TRUE;
+-			if (i < psh->orders)
+-			{
+-				Order[i] = lpStream[dwMemPos];
+-				dwMemPos += 2;
+-			}
+-		}
+-	}
+-	// Pattern Data
+-	for (UINT ipat=0; ipat<psh->patterns; ipat++)
+-	{
+-		if (dwMemPos+8 >= dwMemLength) return TRUE;
+-		UINT packedlen = *((LPDWORD)(lpStream+dwMemPos));
+-		UINT numrows = 1 + (UINT)(lpStream[dwMemPos+4]);
+-		//UINT patchn = 1 + (UINT)(lpStream[dwMemPos+5] & 0x1F);
+-		//UINT patcmds = 1 + (UINT)(lpStream[dwMemPos+5] >> 5);
+-		UINT patnamlen = lpStream[dwMemPos+6];
+-		dwMemPos += 4;
+-		if ((ipat < MAX_PATTERNS) && (packedlen < dwMemLength-dwMemPos) && (numrows >= 8))
+-		{
+-			if ((patnamlen) && (patnamlen < MAX_PATTERNNAME))
+-			{
+-				char s[MAX_PATTERNNAME]; // changed from CHAR
+-				memcpy(s, lpStream+dwMemPos+3, patnamlen);
+-				s[patnamlen] = 0;
+-				SetPatternName(ipat, s);
+-			}
+-			PatternSize[ipat] = numrows;
+-			PatternAllocSize[ipat] = numrows;
+-			Patterns[ipat] = AllocatePattern(numrows, m_nChannels);
+-			if (!Patterns[ipat]) return TRUE;
+-			// Unpack Pattern Data
+-			LPCBYTE psrc = lpStream + dwMemPos;
+-			UINT pos = 3 + patnamlen;
+-			UINT row = 0;
+-			while ((pos < packedlen) && (row < numrows))
+-			{
+-				MODCOMMAND *m = Patterns[ipat] + row * m_nChannels;
+-				UINT byte1 = psrc[pos++];
+-				UINT ch = byte1 & 0x1F;
+-				// Read Note + Instr
+-				if (!(byte1 & 0x40))
+-				{
+-					UINT byte2 = psrc[pos++];
+-					UINT note = byte2 & 0x7F;
+-					if (note) m[ch].note = (note > 1) ? (note-1) : 0xFF;
+-					m[ch].instr = psrc[pos++];
+-					// Read Effect
+-					while (byte2 & 0x80)
+-					{
+-						byte2 = psrc[pos++];
+-						if (byte2 & 0x40)
+-						{
+-							m[ch].volcmd = VOLCMD_VOLUME;
+-							m[ch].vol = byte2 & 0x3F;
+-						} else
+-						{
+-							UINT command = byte2 & 0x3F;
+-							UINT param = psrc[pos++];
+-							if (command == 0x0C)
+-							{
+-								m[ch].volcmd = VOLCMD_VOLUME;
+-								m[ch].vol = param / 2;
+-							} else
+-							if (command < 0x10)
+-							{
+-								m[ch].command = command;
+-								m[ch].param = param;
+-								ConvertModCommand(&m[ch]);
+-							} else
+-							{
+-								// TODO: AMS effects
+-							}
+-						}
+-					}
+-				}
+-				if (byte1 & 0x80) row++;
+-			}
+-		}
+-		dwMemPos += packedlen;
+-	}
+-	// Read Samples
+-	for (UINT iSmp=1; iSmp<=m_nSamples; iSmp++) if (Ins[iSmp].nLength)
+-	{
+-		if (dwMemPos >= dwMemLength - 9) return TRUE;
+-		UINT flags;
+-		if (packedsamples[iSmp] & 0x03)
+-		{
+-			flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_AMS16 : RS_AMS8;
+-		} else
+-		{
+-			flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S;
+-		}
+-		dwMemPos += ReadSample(&Ins[iSmp], flags, (LPSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos);
+-	}
+-	return TRUE;
+-}
+-
+-
+-/////////////////////////////////////////////////////////////////////
+-// AMS Sample unpacking
+-
+-void AMSUnpack(const char *psrc, UINT inputlen, char *pdest, UINT dmax, char packcharacter)
+-{
+-	UINT tmplen = dmax;
+-	signed char *amstmp = new signed char[tmplen];
+-	
+-	if (!amstmp) return;
+-	// Unpack Loop
+-	{
+-		signed char *p = amstmp;
+-		UINT i=0, j=0;
+-		while ((i < inputlen) && (j < tmplen))
+-		{
+-			signed char ch = psrc[i++];
+-			if (ch == packcharacter)
+-			{
+-				BYTE ch2 = psrc[i++];
+-				if (ch2)
+-				{
+-					ch = psrc[i++];
+-					while (ch2--)
+-					{
+-						p[j++] = ch;
+-						if (j >= tmplen) break;
+-					}
+-				} else p[j++] = packcharacter;
+-			} else p[j++] = ch;
+-		}
+-	}
+-	// Bit Unpack Loop
+-	{
+-		signed char *p = amstmp;
+-		UINT bitcount = 0x80, dh;
+-		UINT k=0;
+-		for (UINT i=0; i<dmax; i++)
+-		{
+-			BYTE al = *p++;
+-			dh = 0;
+-			for (UINT count=0; count<8; count++)
+-			{
+-				UINT bl = al & bitcount;
+-				bl = ((bl|(bl<<8)) >> ((dh+8-count) & 7)) & 0xFF;
+-				bitcount = ((bitcount|(bitcount<<8)) >> 1) & 0xFF;
+-				pdest[k++] |= bl;
+-				if (k >= dmax)
+-				{
+-					k = 0;
+-					dh++;
+-				}
+-			}
+-			bitcount = ((bitcount|(bitcount<<8)) >> dh) & 0xFF;
+-		}
+-	}
+-	// Delta Unpack
+-	{
+-		signed char old = 0;
+-		for (UINT i=0; i<dmax; i++)
+-		{
+-			int pos = ((LPBYTE)pdest)[i];
+-			if ((pos != 128) && (pos & 0x80)) pos = -(pos & 0x7F);
+-			old -= (signed char)pos;
+-			pdest[i] = old;
+-		}
+-	}
+-	delete amstmp;
+-}
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_dbm.cxx audacious-plugins-2.5.4/src/modplug/load_dbm.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_dbm.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_dbm.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,370 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>,
+- *          Adam Goode       <adam at evdebs.org> (endian and char fixes for PPC)
+-*/
+-
+-///////////////////////////////////////////////////////////////
+-//
+-// DigiBooster Pro Module Loader (*.dbm)
+-//
+-// Note: this loader doesn't handle multiple songs
+-//
+-///////////////////////////////////////////////////////////////
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#pragma warning(disable:4244)
+-
+-#define DBM_FILE_MAGIC	0x304d4244
+-#define DBM_ID_NAME		0x454d414e
+-#define DBM_NAMELEN		0x2c000000
+-#define DBM_ID_INFO		0x4f464e49
+-#define DBM_INFOLEN		0x0a000000
+-#define DBM_ID_SONG		0x474e4f53
+-#define DBM_ID_INST		0x54534e49
+-#define DBM_ID_VENV		0x564e4556
+-#define DBM_ID_PATT		0x54544150
+-#define DBM_ID_SMPL		0x4c504d53
+-
+-#pragma pack(1)
+-
+-typedef struct DBMFILEHEADER
+-{
+-	DWORD dbm_id;		// "DBM0" = 0x304d4244
+-	WORD trkver;		// Tracker version: 02.15
+-	WORD reserved;
+-	DWORD name_id;		// "NAME" = 0x454d414e
+-	DWORD name_len;		// name length: always 44
+-	CHAR songname[44];
+-	DWORD info_id;		// "INFO" = 0x4f464e49
+-	DWORD info_len;		// 0x0a000000
+-	WORD instruments;
+-	WORD samples;
+-	WORD songs;
+-	WORD patterns;
+-	WORD channels;
+-	DWORD song_id;		// "SONG" = 0x474e4f53
+-	DWORD song_len;
+-	CHAR songname2[44];
+-	WORD orders;
+-//	WORD orderlist[0];	// orderlist[orders] in words
+-} DBMFILEHEADER;
+-
+-typedef struct DBMINSTRUMENT
+-{
+-	CHAR name[30];
+-	WORD sampleno;
+-	WORD volume;
+-	DWORD finetune;
+-	DWORD loopstart;
+-	DWORD looplen;
+-	WORD panning;
+-	WORD flags;
+-} DBMINSTRUMENT;
+-
+-typedef struct DBMENVELOPE
+-{
+-	WORD instrument;
+-	BYTE flags;
+-	BYTE numpoints;
+-	BYTE sustain1;
+-	BYTE loopbegin;
+-	BYTE loopend;
+-	BYTE sustain2;
+-	WORD volenv[2*32];
+-} DBMENVELOPE;
+-
+-typedef struct DBMPATTERN
+-{
+-	WORD rows;
+-	DWORD packedsize;
+-	BYTE patterndata[2];	// [packedsize]
+-} DBMPATTERN;
+-
+-typedef struct DBMSAMPLE
+-{
+-	DWORD flags;
+-	DWORD samplesize;
+-	BYTE sampledata[2];		// [samplesize]
+-} DBMSAMPLE;
+-
+-#pragma pack()
+-
+-
+-BOOL CSoundFile::ReadDBM(const BYTE *lpStream, DWORD dwMemLength)
+-//---------------------------------------------------------------
+-{
+-	DBMFILEHEADER *pfh = (DBMFILEHEADER *)lpStream;
+-	DWORD dwMemPos;
+-	UINT nOrders, nSamples, nInstruments, nPatterns;
+-	
+-	if ((!lpStream) || (dwMemLength <= sizeof(DBMFILEHEADER)) || (!pfh->channels)
+-	 || (pfh->dbm_id != DBM_FILE_MAGIC) || (!pfh->songs) || (pfh->song_id != DBM_ID_SONG)
+-	 || (pfh->name_id != DBM_ID_NAME) || (pfh->name_len != DBM_NAMELEN)
+-	 || (pfh->info_id != DBM_ID_INFO) || (pfh->info_len != DBM_INFOLEN)) return FALSE;
+-	dwMemPos = sizeof(DBMFILEHEADER);
+-	nOrders = bswapBE16(pfh->orders);
+-	if (dwMemPos + 2 * nOrders + 8*3 >= dwMemLength) return FALSE;
+-	nInstruments = bswapBE16(pfh->instruments);
+-	nSamples = bswapBE16(pfh->samples);
+-	nPatterns = bswapBE16(pfh->patterns);
+-	m_nType = MOD_TYPE_DBM;
+-	m_nChannels = bswapBE16(pfh->channels);
+-	if (m_nChannels < 4) m_nChannels = 4;
+-	if (m_nChannels > 64) m_nChannels = 64;
+-	memcpy(m_szNames[0], (pfh->songname[0]) ? pfh->songname : pfh->songname2, 32);
+-	m_szNames[0][31] = 0;
+-	for (UINT iOrd=0; iOrd < nOrders; iOrd++)
+-	{
+-		Order[iOrd] = lpStream[dwMemPos+iOrd*2+1];
+-		if (iOrd >= MAX_ORDERS-2) break;
+-	}
+-	dwMemPos += 2*nOrders;
+-	while (dwMemPos + 10 < dwMemLength)
+-	{
+-		DWORD chunk_id = ((LPDWORD)(lpStream+dwMemPos))[0];
+-		DWORD chunk_size = bswapBE32(((LPDWORD)(lpStream+dwMemPos))[1]);
+-		DWORD chunk_pos;
+-		
+-		dwMemPos += 8;
+-		chunk_pos = dwMemPos;
+-		if ((dwMemPos + chunk_size > dwMemLength) || (chunk_size > dwMemLength)) break;
+-		dwMemPos += chunk_size;
+-		// Instruments
+-		if (chunk_id == DBM_ID_INST)
+-		{
+-			if (nInstruments >= MAX_INSTRUMENTS) nInstruments = MAX_INSTRUMENTS-1;
+-			for (UINT iIns=0; iIns<nInstruments; iIns++)
+-			{
+-				MODINSTRUMENT *psmp;
+-				INSTRUMENTHEADER *penv;
+-				DBMINSTRUMENT *pih;
+-				UINT nsmp;
+-
+-				if (chunk_pos + sizeof(DBMINSTRUMENT) > dwMemPos) break;
+-				if ((penv = new INSTRUMENTHEADER) == NULL) break;
+-				pih = (DBMINSTRUMENT *)(lpStream+chunk_pos);
+-				nsmp = bswapBE16(pih->sampleno);
+-				psmp = ((nsmp) && (nsmp < MAX_SAMPLES)) ? &Ins[nsmp] : NULL;
+-				memset(penv, 0, sizeof(INSTRUMENTHEADER));
+-				memcpy(penv->name, pih->name, 30);
+-				if (psmp)
+-				{
+-					memcpy(m_szNames[nsmp], pih->name, 30);
+-					m_szNames[nsmp][30] = 0;
+-				}
+-				Headers[iIns+1] = penv;
+-				penv->nFadeOut = 1024;	// ???
+-				penv->nGlobalVol = 128;
+-				penv->nPan = bswapBE16(pih->panning);
+-				if ((penv->nPan) && (penv->nPan < 256))
+-					penv->dwFlags = ENV_SETPANNING;
+-				else
+-					penv->nPan = 128;
+-				penv->nPPC = 5*12;
+-				for (UINT i=0; i<120; i++)
+-				{
+-					penv->Keyboard[i] = nsmp;
+-					penv->NoteMap[i] = i+1;
+-				}
+-				// Sample Info
+-				if (psmp)
+-				{
+-					DWORD sflags = bswapBE16(pih->flags);
+-					psmp->nVolume = bswapBE16(pih->volume) * 4;
+-					if ((!psmp->nVolume) || (psmp->nVolume > 256)) psmp->nVolume = 256;
+-					psmp->nGlobalVol = 64;
+-					psmp->nC4Speed = bswapBE32(pih->finetune);
+-					int f2t = FrequencyToTranspose(psmp->nC4Speed);
+-					psmp->RelativeTone = f2t >> 7;
+-					psmp->nFineTune = f2t & 0x7F;
+-					if ((pih->looplen) && (sflags & 3))
+-					{
+-						psmp->nLoopStart = bswapBE32(pih->loopstart);
+-						psmp->nLoopEnd = psmp->nLoopStart + bswapBE32(pih->looplen);
+-						psmp->uFlags |= CHN_LOOP;
+-						psmp->uFlags &= ~CHN_PINGPONGLOOP;
+-						if (sflags & 2) psmp->uFlags |= CHN_PINGPONGLOOP;
+-					}
+-				}
+-				chunk_pos += sizeof(DBMINSTRUMENT);
+-				m_nInstruments = iIns+1;
+-			}
+-			m_dwSongFlags |= SONG_INSTRUMENTMODE;
+-		} else
+-		// Volume Envelopes
+-		if (chunk_id == DBM_ID_VENV)
+-		{
+-			UINT nEnvelopes = lpStream[chunk_pos+1];
+-			
+-			chunk_pos += 2;
+-			for (UINT iEnv=0; iEnv<nEnvelopes; iEnv++)
+-			{
+-				DBMENVELOPE *peh;
+-				UINT nins;
+-				
+-				if (chunk_pos + sizeof(DBMENVELOPE) > dwMemPos) break;
+-				peh = (DBMENVELOPE *)(lpStream+chunk_pos);
+-				nins = bswapBE16(peh->instrument);
+-				if ((nins) && (nins < MAX_INSTRUMENTS) && (Headers[nins]) && (peh->numpoints))
+-				{
+-					INSTRUMENTHEADER *penv = Headers[nins];
+-
+-					if (peh->flags & 1) penv->dwFlags |= ENV_VOLUME;
+-					if (peh->flags & 2) penv->dwFlags |= ENV_VOLSUSTAIN;
+-					if (peh->flags & 4) penv->dwFlags |= ENV_VOLLOOP;
+-					penv->VolEnv.nNodes = peh->numpoints + 1;
+-					if (penv->VolEnv.nNodes > MAX_ENVPOINTS) penv->VolEnv.nNodes = MAX_ENVPOINTS;
+-					penv->VolEnv.nLoopStart = peh->loopbegin;
+-					penv->VolEnv.nLoopEnd = peh->loopend;
+-					penv->VolEnv.nSustainStart = penv->VolEnv.nSustainEnd = peh->sustain1;
+-					for (int i=0; i<penv->VolEnv.nNodes; i++)
+-					{
+-						penv->VolEnv.Ticks[i] = bswapBE16(peh->volenv[i*2]);
+-						penv->VolEnv.Values[i] = (BYTE)bswapBE16(peh->volenv[i*2+1]);
+-					}
+-				}
+-				chunk_pos += sizeof(DBMENVELOPE);
+-			}
+-		} else
+-		// Packed Pattern Data
+-		if (chunk_id == DBM_ID_PATT)
+-		{
+-			if (nPatterns > MAX_PATTERNS) nPatterns = MAX_PATTERNS;
+-			for (UINT iPat=0; iPat<nPatterns; iPat++)
+-			{
+-				DBMPATTERN *pph;
+-				DWORD pksize;
+-				UINT nRows;
+-
+-				if (chunk_pos + sizeof(DBMPATTERN) > dwMemPos) break;
+-				pph = (DBMPATTERN *)(lpStream+chunk_pos);
+-				pksize = bswapBE32(pph->packedsize);
+-				if ((chunk_pos + pksize + 6 > dwMemPos) || (pksize > dwMemPos)) break;
+-				nRows = bswapBE16(pph->rows);
+-				if ((nRows >= 4) && (nRows <= 256))
+-				{
+-					MODCOMMAND *m = AllocatePattern(nRows, m_nChannels);
+-					if (m)
+-					{
+-						LPBYTE pkdata = (LPBYTE)&pph->patterndata;
+-						UINT row = 0;
+-						UINT i = 0;
+-
+-						PatternSize[iPat] = nRows;
+-						PatternAllocSize[iPat] = nRows;
+-						Patterns[iPat] = m;
+-						while ((i+3<pksize) && (row < nRows))
+-						{
+-							UINT ch = pkdata[i++];
+-
+-							if (ch)
+-							{
+-								BYTE b = pkdata[i++];
+-								ch--;
+-								if (ch < m_nChannels)
+-								{
+-									if (b & 0x01)
+-									{
+-										UINT note = pkdata[i++];
+-
+-										if (note == 0x1F) note = 0xFF; else
+-										if ((note) && (note < 0xFE))
+-										{
+-											note = ((note >> 4)*12) + (note & 0x0F) + 13;
+-										}
+-										m[ch].note = note;
+-									}
+-									if (b & 0x02) m[ch].instr = pkdata[i++];
+-									if (b & 0x3C)
+-									{
+-										UINT cmd1 = 0xFF, param1 = 0, cmd2 = 0xFF, param2 = 0;
+-										if (b & 0x04) cmd1 = (UINT)pkdata[i++];
+-										if (b & 0x08) param1 = pkdata[i++];
+-										if (b & 0x10) cmd2 = (UINT)pkdata[i++];
+-										if (b & 0x20) param2 = pkdata[i++];
+-										if (cmd1 == 0x0C)
+-										{
+-											m[ch].volcmd = VOLCMD_VOLUME;
+-											m[ch].vol = param1;
+-											cmd1 = 0xFF;
+-										} else
+-										if (cmd2 == 0x0C)
+-										{
+-											m[ch].volcmd = VOLCMD_VOLUME;
+-											m[ch].vol = param2;
+-											cmd2 = 0xFF;
+-										}
+-										if ((cmd1 > 0x13) || ((cmd1 >= 0x10) && (cmd2 < 0x10)))
+-										{
+-											cmd1 = cmd2;
+-											param1 = param2;
+-											cmd2 = 0xFF;
+-										}
+-										if (cmd1 <= 0x13)
+-										{
+-											m[ch].command = cmd1;
+-											m[ch].param = param1;
+-											ConvertModCommand(&m[ch]);
+-										}
+-									}
+-								} else
+-								{
+-									if (b & 0x01) i++;
+-									if (b & 0x02) i++;
+-									if (b & 0x04) i++;
+-									if (b & 0x08) i++;
+-									if (b & 0x10) i++;
+-									if (b & 0x20) i++;
+-								}
+-							} else
+-							{
+-								row++;
+-								m += m_nChannels;
+-							}
+-						}
+-					}
+-				}
+-				chunk_pos += 6 + pksize;
+-			}
+-		} else
+-		// Reading Sample Data
+-		if (chunk_id == DBM_ID_SMPL)
+-		{
+-			if (nSamples >= MAX_SAMPLES) nSamples = MAX_SAMPLES-1;
+-			m_nSamples = nSamples;
+-			for (UINT iSmp=1; iSmp<=nSamples; iSmp++)
+-			{
+-				MODINSTRUMENT *pins;
+-				DBMSAMPLE *psh;
+-				DWORD samplesize;
+-				DWORD sampleflags;
+-
+-				if (chunk_pos + sizeof(DBMSAMPLE) >= dwMemPos) break;
+-				psh = (DBMSAMPLE *)(lpStream+chunk_pos);
+-				chunk_pos += 8;
+-				samplesize = bswapBE32(psh->samplesize);
+-				sampleflags = bswapBE32(psh->flags);
+-				pins = &Ins[iSmp];
+-				pins->nLength = samplesize;
+-				if (sampleflags & 2)
+-				{
+-					pins->uFlags |= CHN_16BIT;
+-					samplesize <<= 1;
+-				}
+-				if ((chunk_pos+samplesize > dwMemPos) || (samplesize > dwMemLength)) break;
+-				if (sampleflags & 3)
+-				{
+-					ReadSample(pins, (pins->uFlags & CHN_16BIT) ? RS_PCM16M : RS_PCM8S,
+-								(LPSTR)(psh->sampledata), samplesize);
+-				}
+-				chunk_pos += samplesize;
+-			}
+-		}
+-	}
+-	return TRUE;
+-}
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_dmf.cxx audacious-plugins-2.5.4/src/modplug/load_dmf.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_dmf.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_dmf.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,607 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-///////////////////////////////////////////////////////
+-// DMF DELUSION DIGITAL MUSIC FILEFORMAT (X-Tracker) //
+-///////////////////////////////////////////////////////
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#define DMFLOG
+-
+-//#pragma warning(disable:4244)
+-
+-#pragma pack(1)
+-
+-typedef struct DMFHEADER
+-{
+-	DWORD id;				// "DDMF" = 0x464d4444
+-	BYTE version;			// 4
+-	CHAR trackername[8];	// "XTRACKER"
+-	CHAR songname[30];
+-	CHAR composer[20];
+-	BYTE date[3];
+-} DMFHEADER;
+-
+-typedef struct DMFINFO
+-{
+-	DWORD id;			// "INFO"
+-	DWORD infosize;
+-} DMFINFO;
+-
+-typedef struct DMFSEQU
+-{
+-	DWORD id;			// "SEQU"
+-	DWORD seqsize;
+-	WORD loopstart;
+-	WORD loopend;
+-	WORD sequ[2];
+-} DMFSEQU;
+-
+-typedef struct DMFPATT
+-{
+-	DWORD id;			// "PATT"
+-	DWORD patsize;
+-	WORD numpat;		// 1-1024
+-	BYTE tracks;
+-	BYTE firstpatinfo;
+-} DMFPATT;
+-
+-typedef struct DMFTRACK
+-{
+-	BYTE tracks;
+-	BYTE beat;		// [hi|lo] -> hi=ticks per beat, lo=beats per measure
+-	WORD ticks;		// max 512
+-	DWORD jmpsize;
+-} DMFTRACK;
+-
+-typedef struct DMFSMPI
+-{
+-	DWORD id;
+-	DWORD size;
+-	BYTE samples;
+-} DMFSMPI;
+-
+-typedef struct DMFSAMPLE
+-{
+-	DWORD len;
+-	DWORD loopstart;
+-	DWORD loopend;
+-	WORD c3speed;
+-	BYTE volume;
+-	BYTE flags;
+-} DMFSAMPLE;
+-
+-#pragma pack()
+-
+-
+-#ifdef DMFLOG
+-extern void Log(LPCSTR s, ...);
+-#endif
+-
+-
+-BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
+-//---------------------------------------------------------------
+-{
+-	DMFHEADER *pfh = (DMFHEADER *)lpStream;
+-	DMFINFO *psi;
+-	DMFSEQU *sequ;
+-	DWORD dwMemPos;
+-	BYTE infobyte[32];
+-	BYTE smplflags[MAX_SAMPLES];
+-
+-	if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
+-	if ((pfh->id != 0x464d4444) || (!pfh->version) || (pfh->version & 0xF0)) return FALSE;
+-	dwMemPos = 66;
+-	memcpy(m_szNames[0], pfh->songname, 30);
+-	m_szNames[0][30] = 0;
+-	m_nType = MOD_TYPE_DMF;
+-	m_nChannels = 0;
+-#ifdef DMFLOG
+-	Log("DMF version %d: \"%s\": %d bytes (0x%04X)\n", pfh->version, m_szNames[0], dwMemLength, dwMemLength);
+-#endif
+-	while (dwMemPos + 7 < dwMemLength)
+-	{
+-		DWORD id = *((LPDWORD)(lpStream+dwMemPos));
+-
+-		switch(id)
+-		{
+-		// "INFO"
+-		case 0x4f464e49:
+-		// "CMSG"
+-		case 0x47534d43:
+-			psi = (DMFINFO *)(lpStream+dwMemPos);
+-			if (id == 0x47534d43) dwMemPos++;
+-			if ((psi->infosize > dwMemLength) || (psi->infosize + dwMemPos + 8 > dwMemLength)) goto dmfexit;
+-			if ((psi->infosize >= 8) && (!m_lpszSongComments))
+-			{
+-			    m_lpszSongComments = new char[psi->infosize]; // changed from CHAR
+-				if (m_lpszSongComments)
+-				{
+-					for (UINT i=0; i<psi->infosize-1; i++)
+-					{
+-						CHAR c = lpStream[dwMemPos+8+i];
+-						if ((i % 40) == 39)
+-							m_lpszSongComments[i] = 0x0d;
+-						else
+-							m_lpszSongComments[i] = (c < ' ') ? ' ' : c;
+-					}
+-					m_lpszSongComments[psi->infosize-1] = 0;
+-				}
+-			}
+-			dwMemPos += psi->infosize + 8 - 1;
+-			break;
+-
+-		// "SEQU"
+-		case 0x55514553:
+-			sequ = (DMFSEQU *)(lpStream+dwMemPos);
+-			if ((sequ->seqsize >= dwMemLength) || (dwMemPos + sequ->seqsize + 12 > dwMemLength)) goto dmfexit;
+-			{
+-				UINT nseq = sequ->seqsize >> 1;
+-				if (nseq >= MAX_ORDERS-1) nseq = MAX_ORDERS-1;
+-				if (sequ->loopstart < nseq) m_nRestartPos = sequ->loopstart;
+-				for (UINT i=0; i<nseq; i++) Order[i] = (BYTE)sequ->sequ[i];
+-			}
+-			dwMemPos += sequ->seqsize + 8;
+-			break;
+-
+-		// "PATT"
+-		case 0x54544150:
+-			if (!m_nChannels)
+-			{
+-				DMFPATT *patt = (DMFPATT *)(lpStream+dwMemPos);
+-				UINT numpat;
+-				DWORD dwPos = dwMemPos + 11;
+-				if ((patt->patsize >= dwMemLength) || (dwMemPos + patt->patsize + 8 > dwMemLength)) goto dmfexit;
+-				numpat = patt->numpat;
+-				if (numpat > MAX_PATTERNS) numpat = MAX_PATTERNS;
+-				m_nChannels = patt->tracks;
+-				if (m_nChannels < patt->firstpatinfo) m_nChannels = patt->firstpatinfo;
+-				if (m_nChannels > 32) m_nChannels = 32;
+-				if (m_nChannels < 4) m_nChannels = 4;
+-				for (UINT npat=0; npat<numpat; npat++)
+-				{
+-					DMFTRACK *pt = (DMFTRACK *)(lpStream+dwPos);
+-				#ifdef DMFLOG
+-					Log("Pattern #%d: %d tracks, %d rows\n", npat, pt->tracks, pt->ticks);
+-				#endif
+-					UINT tracks = pt->tracks;
+-					if (tracks > 32) tracks = 32;
+-					UINT ticks = pt->ticks;
+-					if (ticks > 256) ticks = 256;
+-					if (ticks < 16) ticks = 16;
+-					dwPos += 8;
+-					if ((pt->jmpsize >= dwMemLength) || (dwPos + pt->jmpsize + 4 >= dwMemLength)) break;
+-					PatternSize[npat] = (WORD)ticks;
+-					PatternAllocSize[npat] = (WORD)ticks;
+-					MODCOMMAND *m = AllocatePattern(PatternSize[npat], m_nChannels);
+-					if (!m) goto dmfexit;
+-					Patterns[npat] = m;
+-					DWORD d = dwPos;
+-					dwPos += pt->jmpsize;
+-					UINT ttype = 1;
+-					UINT tempo = 125;
+-					UINT glbinfobyte = 0;
+-					UINT pbeat = (pt->beat & 0xf0) ? pt->beat>>4 : 8;
+-					BOOL tempochange = (pt->beat & 0xf0) ? TRUE : FALSE;
+-					memset(infobyte, 0, sizeof(infobyte));
+-					for (UINT row=0; row<ticks; row++)
+-					{
+-						MODCOMMAND *p = &m[row*m_nChannels];
+-						// Parse track global effects
+-						if (!glbinfobyte)
+-						{
+-							BYTE info = lpStream[d++];
+-							BYTE infoval = 0;
+-							if ((info & 0x80) && (d < dwPos)) glbinfobyte = lpStream[d++];
+-							info &= 0x7f;
+-							if ((info) && (d < dwPos)) infoval = lpStream[d++];
+-							switch(info)
+-							{
+-							case 1:	ttype = 0; tempo = infoval; tempochange = TRUE; break;
+-							case 2: ttype = 1; tempo = infoval; tempochange = TRUE; break;
+-							case 3: pbeat = infoval>>4; tempochange = ttype; break;
+-							#ifdef DMFLOG
+-							default: if (info) Log("GLB: %02X.%02X\n", info, infoval);
+-							#endif
+-							}
+-						} else
+-						{
+-							glbinfobyte--;
+-						}
+-						// Parse channels
+-						for (UINT i=0; i<tracks; i++) if (!infobyte[i])
+-						{
+-							MODCOMMAND cmd = {0,0,0,0,0,0};
+-							BYTE info = lpStream[d++];
+-							if (info & 0x80) infobyte[i] = lpStream[d++];
+-							// Instrument
+-							if (info & 0x40)
+-							{
+-								cmd.instr = lpStream[d++];
+-							}
+-							// Note
+-							if (info & 0x20)
+-							{
+-								cmd.note = lpStream[d++];
+-								if ((cmd.note) && (cmd.note < 0xfe)) cmd.note &= 0x7f;
+-								if ((cmd.note) && (cmd.note < 128)) cmd.note += 24;
+-							}
+-							// Volume
+-							if (info & 0x10)
+-							{
+-								cmd.volcmd = VOLCMD_VOLUME;
+-								cmd.vol = (lpStream[d++]+3)>>2;
+-							}
+-							// Effect 1
+-							if (info & 0x08)
+-							{
+-								BYTE efx = lpStream[d++];
+-								BYTE eval = lpStream[d++];
+-								switch(efx)
+-								{
+-								// 1: Key Off
+-								case 1: if (!cmd.note) cmd.note = 0xFE; break;
+-								// 2: Set Loop
+-								// 4: Sample Delay
+-								case 4: if (eval&0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xD0; } break;
+-								// 5: Retrig
+-								case 5: if (eval&0xe0) { cmd.command = CMD_RETRIG; cmd.param = (eval>>5); } break;
+-								// 6: Offset
+-								case 6: cmd.command = CMD_OFFSET; cmd.param = eval; break;
+-								#ifdef DMFLOG
+-								default: Log("FX1: %02X.%02X\n", efx, eval);
+-								#endif
+-								}
+-							}
+-							// Effect 2
+-							if (info & 0x04)
+-							{
+-								BYTE efx = lpStream[d++];
+-								BYTE eval = lpStream[d++];
+-								switch(efx)
+-								{
+-								// 1: Finetune
+-								case 1: if (eval&0xf0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>4)|0x20; } break;
+-								// 2: Note Delay
+-								case 2: if (eval&0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xD0; } break;
+-								// 3: Arpeggio
+-								case 3: if (eval) { cmd.command = CMD_ARPEGGIO; cmd.param = eval; } break;
+-								// 4: Portamento Up
+-								case 4: cmd.command = CMD_PORTAMENTOUP; cmd.param = (eval >= 0xe0) ? 0xdf : eval; break;
+-								// 5: Portamento Down
+-								case 5: cmd.command = CMD_PORTAMENTODOWN; cmd.param = (eval >= 0xe0) ? 0xdf : eval; break;
+-								// 6: Tone Portamento
+-								case 6: cmd.command = CMD_TONEPORTAMENTO; cmd.param = eval; break;
+-								// 8: Vibrato
+-								case 8: cmd.command = CMD_VIBRATO; cmd.param = eval; break;
+-								// 12: Note cut
+-								case 12: if (eval & 0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xc0; }
+-										else if (!cmd.note) { cmd.note = 0xfe; } break;
+-								#ifdef DMFLOG
+-								default: Log("FX2: %02X.%02X\n", efx, eval);
+-								#endif
+-								}
+-							}
+-							// Effect 3
+-							if (info & 0x02)
+-							{
+-								BYTE efx = lpStream[d++];
+-								BYTE eval = lpStream[d++];
+-								switch(efx)
+-								{
+-								// 1: Vol Slide Up
+-								case 1: if (eval == 0xff) break;
+-										eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
+-										cmd.command = CMD_VOLUMESLIDE; cmd.param = eval<<4; break;
+-								// 2: Vol Slide Down
+-								case 2:	if (eval == 0xff) break;
+-										eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
+-										cmd.command = CMD_VOLUMESLIDE; cmd.param = eval; break;
+-								// 7: Set Pan
+-								case 7: if (!cmd.volcmd) { cmd.volcmd = VOLCMD_PANNING; cmd.vol = (eval+3)>>2; }
+-										else { cmd.command = CMD_PANNING8; cmd.param = eval; } break;
+-								// 8: Pan Slide Left
+-								case 8: eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
+-										cmd.command = CMD_PANNINGSLIDE; cmd.param = eval<<4; break;
+-								// 9: Pan Slide Right
+-								case 9: eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
+-										cmd.command = CMD_PANNINGSLIDE; cmd.param = eval; break;
+-								#ifdef DMFLOG
+-								default: Log("FX3: %02X.%02X\n", efx, eval);
+-								#endif
+-
+-								}
+-							}
+-							// Store effect
+-							if (i < m_nChannels) p[i] = cmd;
+-							if (d > dwPos)
+-							{
+-							#ifdef DMFLOG
+-								Log("Unexpected EOP: row=%d\n", row);
+-							#endif
+-								break;
+-							}
+-						} else
+-						{
+-							infobyte[i]--;
+-						}
+-
+-						// Find free channel for tempo change
+-						if (tempochange)
+-						{
+-							tempochange = FALSE;
+-							UINT speed=6, modtempo=tempo;
+-							UINT rpm = ((ttype) && (pbeat)) ? tempo*pbeat : (tempo+1)*15;
+-							for (speed=30; speed>1; speed--)
+-							{
+-								modtempo = rpm*speed/24;
+-								if (modtempo <= 200) break;
+-								if ((speed < 6) && (modtempo < 256)) break;
+-							}
+-						#ifdef DMFLOG
+-							Log("Tempo change: ttype=%d pbeat=%d tempo=%3d -> speed=%d tempo=%d\n",
+-								ttype, pbeat, tempo, speed, modtempo);
+-						#endif
+-							for (UINT ich=0; ich<m_nChannels; ich++) if (!p[ich].command)
+-							{
+-								if (speed)
+-								{
+-									p[ich].command = CMD_SPEED;
+-									p[ich].param = (BYTE)speed;
+-									speed = 0;
+-								} else
+-								if ((modtempo >= 32) && (modtempo < 256))
+-								{
+-									p[ich].command = CMD_TEMPO;
+-									p[ich].param = (BYTE)modtempo;
+-									modtempo = 0;
+-								} else
+-								{
+-									break;
+-								}
+-							}
+-						}
+-						if (d >= dwPos) break;
+-					}
+-				#ifdef DMFLOG
+-					Log(" %d/%d bytes remaining\n", dwPos-d, pt->jmpsize);
+-				#endif
+-					if (dwPos + 8 >= dwMemLength) break;
+-				}
+-				dwMemPos += patt->patsize + 8;
+-			}
+-			break;
+-
+-		// "SMPI": Sample Info
+-		case 0x49504d53:
+-			{
+-				DMFSMPI *pds = (DMFSMPI *)(lpStream+dwMemPos);
+-				if (pds->size <= dwMemLength - dwMemPos)
+-				{
+-					DWORD dwPos = dwMemPos + 9;
+-					m_nSamples = pds->samples;
+-					if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES-1;
+-					for (UINT iSmp=1; iSmp<=m_nSamples; iSmp++)
+-					{
+-						UINT namelen = lpStream[dwPos];
+-						smplflags[iSmp] = 0;
+-						if (dwPos+namelen+1+sizeof(DMFSAMPLE) > dwMemPos+pds->size+8) break;
+-						if (namelen)
+-						{
+-							UINT rlen = (namelen < 32) ? namelen : 31;
+-							memcpy(m_szNames[iSmp], lpStream+dwPos+1, rlen);
+-							m_szNames[iSmp][rlen] = 0;
+-						}
+-						dwPos += namelen + 1;
+-						DMFSAMPLE *psh = (DMFSAMPLE *)(lpStream+dwPos);
+-						MODINSTRUMENT *psmp = &Ins[iSmp];
+-						psmp->nLength = psh->len;
+-						psmp->nLoopStart = psh->loopstart;
+-						psmp->nLoopEnd = psh->loopend;
+-						psmp->nC4Speed = psh->c3speed;
+-						psmp->nGlobalVol = 64;
+-						psmp->nVolume = (psh->volume) ? ((WORD)psh->volume)+1 : (WORD)256;
+-						psmp->uFlags = (psh->flags & 2) ? CHN_16BIT : 0;
+-						if (psmp->uFlags & CHN_16BIT) psmp->nLength >>= 1;
+-						if (psh->flags & 1) psmp->uFlags |= CHN_LOOP;
+-						smplflags[iSmp] = psh->flags;
+-						dwPos += (pfh->version < 8) ? 22 : 30;
+-					#ifdef DMFLOG
+-						Log("SMPI %d/%d: len=%d flags=0x%02X\n", iSmp, m_nSamples, psmp->nLength, psh->flags);
+-					#endif
+-					}
+-				}
+-				dwMemPos += pds->size + 8;
+-			}
+-			break;
+-
+-		// "SMPD": Sample Data
+-		case 0x44504d53:
+-			{
+-				DWORD dwPos = dwMemPos + 8;
+-				UINT ismpd = 0;
+-				for (UINT iSmp=1; iSmp<=m_nSamples; iSmp++)
+-				{
+-					ismpd++;
+-					DWORD pksize;
+-					if (dwPos + 4 >= dwMemLength)
+-					{
+-					#ifdef DMFLOG
+-						Log("Unexpected EOF at sample %d/%d! (pos=%d)\n", iSmp, m_nSamples, dwPos);
+-					#endif
+-						break;
+-					}
+-					pksize = *((LPDWORD)(lpStream+dwPos));
+-				#ifdef DMFLOG
+-					Log("sample %d: pos=0x%X pksize=%d ", iSmp, dwPos, pksize);
+-					Log("len=%d flags=0x%X [%08X]\n", Ins[iSmp].nLength, smplflags[ismpd], *((LPDWORD)(lpStream+dwPos+4)));
+-				#endif
+-					dwPos += 4;
+-					if (pksize > dwMemLength - dwPos)
+-					{
+-					#ifdef DMFLOG
+-						Log("WARNING: pksize=%d, but only %d bytes left\n", pksize, dwMemLength-dwPos);
+-					#endif
+-						pksize = dwMemLength - dwPos;
+-					}
+-					if ((pksize) && (iSmp <= m_nSamples))
+-					{
+-						UINT flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S;
+-						if (smplflags[ismpd] & 4) flags = (Ins[iSmp].uFlags & CHN_16BIT) ? RS_DMF16 : RS_DMF8;
+-						ReadSample(&Ins[iSmp], flags, (LPSTR)(lpStream+dwPos), pksize);
+-					}
+-					dwPos += pksize;
+-				}
+-				dwMemPos = dwPos;
+-			}
+-			break;
+-
+-		// "ENDE": end of file
+-		case 0x45444e45:
+-			goto dmfexit;
+-		
+-		// Unrecognized id, or "ENDE" field
+-		default:
+-			dwMemPos += 4;
+-			break;
+-		}
+-	}
+-dmfexit:
+-	if (!m_nChannels)
+-	{
+-		if (!m_nSamples)
+-		{
+-			m_nType = MOD_TYPE_NONE;
+-			return FALSE;
+-		}
+-		m_nChannels = 4;
+-	}
+-	return TRUE;
+-}
+-
+-
+-///////////////////////////////////////////////////////////////////////
+-// DMF Compression
+-
+-#pragma pack(1)
+-
+-typedef struct DMF_HNODE
+-{
+-	short int left, right;
+-	BYTE value;
+-} DMF_HNODE;
+-
+-typedef struct DMF_HTREE
+-{
+-	LPBYTE ibuf, ibufmax;
+-	DWORD bitbuf;
+-	UINT bitnum;
+-	UINT lastnode, nodecount;
+-	DMF_HNODE nodes[256];
+-} DMF_HTREE;
+-
+-#pragma pack()
+-
+-
+-// DMF Huffman ReadBits
+-BYTE DMFReadBits(DMF_HTREE *tree, UINT nbits)
+-//-------------------------------------------
+-{
+-	BYTE x = 0, bitv = 1;
+-	while (nbits--)
+-	{
+-		if (tree->bitnum)
+-		{
+-			tree->bitnum--;
+-		} else
+-		{
+-			tree->bitbuf = (tree->ibuf < tree->ibufmax) ? *(tree->ibuf++) : 0;
+-			tree->bitnum = 7;
+-		}
+-		if (tree->bitbuf & 1) x |= bitv;
+-		bitv <<= 1;
+-		tree->bitbuf >>= 1;
+-	}
+-	return x;
+-}
+-
+-//
+-// tree: [8-bit value][12-bit index][12-bit index] = 32-bit
+-//
+-
+-void DMFNewNode(DMF_HTREE *tree)
+-//------------------------------
+-{
+-	BYTE isleft, isright;
+-	UINT actnode;
+-
+-	actnode = tree->nodecount;
+-	if (actnode > 255) return;
+-	tree->nodes[actnode].value = DMFReadBits(tree, 7);
+-	isleft = DMFReadBits(tree, 1);
+-	isright = DMFReadBits(tree, 1);
+-	actnode = tree->lastnode;
+-	if (actnode > 255) return;
+-	tree->nodecount++;
+-	tree->lastnode = tree->nodecount;
+-	if (isleft)
+-	{
+-		tree->nodes[actnode].left = tree->lastnode;
+-		DMFNewNode(tree);
+-	} else
+-	{
+-		tree->nodes[actnode].left = -1;
+-	}
+-	tree->lastnode = tree->nodecount;
+-	if (isright)
+-	{
+-		tree->nodes[actnode].right = tree->lastnode;
+-		DMFNewNode(tree);
+-	} else
+-	{
+-		tree->nodes[actnode].right = -1;
+-	}
+-}
+-
+-
+-int DMFUnpack(LPBYTE psample, LPBYTE ibuf, LPBYTE ibufmax, UINT maxlen)
+-//----------------------------------------------------------------------
+-{
+-	DMF_HTREE tree;
+-	UINT actnode;
+-	BYTE value, sign, delta = 0;
+-	
+-	memset(&tree, 0, sizeof(tree));
+-	tree.ibuf = ibuf;
+-	tree.ibufmax = ibufmax;
+-	DMFNewNode(&tree);
+-	value = 0;
+-	for (UINT i=0; i<maxlen; i++)
+-	{
+-		actnode = 0;
+-		sign = DMFReadBits(&tree, 1);
+-		do
+-		{
+-			if (DMFReadBits(&tree, 1))
+-				actnode = tree.nodes[actnode].right;
+-			else
+-				actnode = tree.nodes[actnode].left;
+-			if (actnode > 255) break;
+-			delta = tree.nodes[actnode].value;
+-			if ((tree.ibuf >= tree.ibufmax) && (!tree.bitnum)) break;
+-		} while ((tree.nodes[actnode].left >= 0) && (tree.nodes[actnode].right >= 0));
+-		if (sign) delta ^= 0xFF;
+-		value += delta;
+-		psample[i] = (i) ? value : 0;
+-	}
+-#ifdef DMFLOG
+-//	Log("DMFUnpack: %d remaining bytes\n", tree.ibufmax-tree.ibuf);
+-#endif
+-	return tree.ibuf - ibuf;
+-}
+-
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_dsm.cxx audacious-plugins-2.5.4/src/modplug/load_dsm.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_dsm.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_dsm.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,237 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-//////////////////////////////////////////////
+-// DSIK Internal Format (DSM) module loader //
+-//////////////////////////////////////////////
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-#pragma pack(1)
+-
+-#define DSMID_RIFF	0x46464952	// "RIFF"
+-#define DSMID_DSMF	0x464d5344	// "DSMF"
+-#define DSMID_SONG	0x474e4f53	// "SONG"
+-#define DSMID_INST	0x54534e49	// "INST"
+-#define DSMID_PATT	0x54544150	// "PATT"
+-
+-
+-typedef struct DSMNOTE
+-{
+-	BYTE note,ins,vol,cmd,inf;
+-} DSMNOTE;
+-
+-
+-typedef struct DSMINST
+-{
+-	DWORD id_INST;
+-	DWORD inst_len;
+-	CHAR filename[13];
+-	BYTE flags;
+-	BYTE flags2;
+-	BYTE volume;
+-	DWORD length;
+-	DWORD loopstart;
+-	DWORD loopend;
+-	DWORD reserved1;
+-	WORD c2spd;
+-	WORD reserved2;
+-	CHAR samplename[28];
+-} DSMINST;
+-
+-
+-typedef struct DSMFILEHEADER
+-{
+-	DWORD id_RIFF;	// "RIFF"
+-	DWORD riff_len;
+-	DWORD id_DSMF;	// "DSMF"
+-	DWORD id_SONG;	// "SONG"
+-	DWORD song_len;
+-} DSMFILEHEADER;
+-
+-
+-typedef struct DSMSONG
+-{
+-	CHAR songname[28];
+-	WORD reserved1;
+-	WORD flags;
+-	DWORD reserved2;
+-	WORD numord;
+-	WORD numsmp;
+-	WORD numpat;
+-	WORD numtrk;
+-	BYTE globalvol;
+-	BYTE mastervol;
+-	BYTE speed;
+-	BYTE bpm;
+-	BYTE panpos[16];
+-	BYTE orders[128];
+-} DSMSONG;
+-
+-typedef struct DSMPATT
+-{
+-	DWORD id_PATT;
+-	DWORD patt_len;
+-	BYTE dummy1;
+-	BYTE dummy2;
+-} DSMPATT;
+-
+-#pragma pack()
+-
+-
+-BOOL CSoundFile::ReadDSM(LPCBYTE lpStream, DWORD dwMemLength)
+-//-----------------------------------------------------------
+-{
+-	DSMFILEHEADER *pfh = (DSMFILEHEADER *)lpStream;
+-	DSMSONG *psong;
+-	DWORD dwMemPos;
+-	UINT nPat, nSmp;
+-
+-	if ((!lpStream) || (dwMemLength < 1024) || (pfh->id_RIFF != DSMID_RIFF)
+-	 || (pfh->riff_len + 8 > dwMemLength) || (pfh->riff_len < 1024)
+-	 || (pfh->id_DSMF != DSMID_DSMF) || (pfh->id_SONG != DSMID_SONG)
+-	 || (pfh->song_len > dwMemLength)) return FALSE;
+-	psong = (DSMSONG *)(lpStream + sizeof(DSMFILEHEADER));
+-	dwMemPos = sizeof(DSMFILEHEADER) + pfh->song_len;
+-	m_nType = MOD_TYPE_DSM;
+-	m_nChannels = psong->numtrk;
+-	if (m_nChannels < 4) m_nChannels = 4;
+-	if (m_nChannels > 16) m_nChannels = 16;
+-	m_nSamples = psong->numsmp;
+-	if (m_nSamples > MAX_SAMPLES) m_nSamples = MAX_SAMPLES;
+-	m_nDefaultSpeed = psong->speed;
+-	m_nDefaultTempo = psong->bpm;
+-	m_nDefaultGlobalVolume = psong->globalvol << 2;
+-	if ((!m_nDefaultGlobalVolume) || (m_nDefaultGlobalVolume > 256)) m_nDefaultGlobalVolume = 256;
+-	m_nSongPreAmp = psong->mastervol & 0x7F;
+-	for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
+-	{
+-		Order[iOrd] = (BYTE)((iOrd < psong->numord) ? psong->orders[iOrd] : 0xFF);
+-	}
+-	for (UINT iPan=0; iPan<16; iPan++)
+-	{
+-		ChnSettings[iPan].nPan = 0x80;
+-		if (psong->panpos[iPan] <= 0x80)
+-		{
+-			ChnSettings[iPan].nPan = psong->panpos[iPan] << 1;
+-		}
+-	}
+-	memcpy(m_szNames[0], psong->songname, 28);
+-	nPat = 0;
+-	nSmp = 1;
+-	while (dwMemPos < dwMemLength - 8)
+-	{
+-		DSMPATT *ppatt = (DSMPATT *)(lpStream + dwMemPos);
+-		DSMINST *pins = (DSMINST *)(lpStream+dwMemPos);
+-		// Reading Patterns
+-		if (ppatt->id_PATT == DSMID_PATT)
+-		{
+-			dwMemPos += 8;
+-			if (dwMemPos + ppatt->patt_len >= dwMemLength) break;
+-			DWORD dwPos = dwMemPos;
+-			dwMemPos += ppatt->patt_len;
+-			MODCOMMAND *m = AllocatePattern(64, m_nChannels);
+-			if (!m) break;
+-			PatternSize[nPat] = 64;
+-			PatternAllocSize[nPat] = 64;
+-			Patterns[nPat] = m;
+-			UINT row = 0;
+-			while ((row < 64) && (dwPos + 2 <= dwMemPos))
+-			{
+-				UINT flag = lpStream[dwPos++];
+-				if (flag)
+-				{
+-					UINT ch = (flag & 0x0F) % m_nChannels;
+-					if (flag & 0x80)
+-					{
+-						UINT note = lpStream[dwPos++];
+-						if (note)
+-						{
+-							if (note <= 12*9) note += 12;
+-							m[ch].note = (BYTE)note;
+-						}
+-					}
+-					if (flag & 0x40)
+-					{
+-						m[ch].instr = lpStream[dwPos++];
+-					}
+-					if (flag & 0x20)
+-					{
+-						m[ch].volcmd = VOLCMD_VOLUME;
+-						m[ch].vol = lpStream[dwPos++];
+-					}
+-					if (flag & 0x10)
+-					{
+-						UINT command = lpStream[dwPos++];
+-						UINT param = lpStream[dwPos++];
+-						switch(command)
+-						{
+-						// 4-bit Panning
+-						case 0x08:
+-							switch(param & 0xF0)
+-							{
+-							case 0x00: param <<= 4; break;
+-							case 0x10: command = 0x0A; param = (param & 0x0F) << 4; break;
+-							case 0x20: command = 0x0E; param = (param & 0x0F) | 0xA0; break;
+-							case 0x30: command = 0x0E; param = (param & 0x0F) | 0x10; break;
+-							case 0x40: command = 0x0E; param = (param & 0x0F) | 0x20; break;
+-							default: command = 0;
+-							}
+-							break;
+-						// Portamentos
+-						case 0x11:
+-						case 0x12:
+-							command &= 0x0F;
+-							break;
+-						// 3D Sound (?)
+-						case 0x13:
+-							command = 'X' - 55;
+-							param = 0x91;
+-							break;
+-						default:
+-							// Volume + Offset (?)
+-							command = ((command & 0xF0) == 0x20) ? 0x09 : 0;
+-						}
+-						m[ch].command = (BYTE)command;
+-						m[ch].param = (BYTE)param;
+-						if (command) ConvertModCommand(&m[ch]);
+-					}
+-				} else
+-				{
+-					m += m_nChannels;
+-					row++;
+-				}
+-			}
+-			nPat++;
+-		} else
+-		// Reading Samples
+-		if ((nSmp <= m_nSamples) && (pins->id_INST == DSMID_INST))
+-		{
+-			if (dwMemPos + pins->inst_len >= dwMemLength - 8) break;
+-			DWORD dwPos = dwMemPos + sizeof(DSMINST);
+-			dwMemPos += 8 + pins->inst_len;
+-			memcpy(m_szNames[nSmp], pins->samplename, 28);
+-			MODINSTRUMENT *psmp = &Ins[nSmp];
+-			memcpy(psmp->name, pins->filename, 13);
+-			psmp->nGlobalVol = 64;
+-			psmp->nC4Speed = pins->c2spd;
+-			psmp->uFlags = (WORD)((pins->flags & 1) ? CHN_LOOP : 0);
+-			psmp->nLength = pins->length;
+-			psmp->nLoopStart = pins->loopstart;
+-			psmp->nLoopEnd = pins->loopend;
+-			psmp->nVolume = (WORD)(pins->volume << 2);
+-			if (psmp->nVolume > 256) psmp->nVolume = 256;
+-			UINT smptype = (pins->flags & 2) ? RS_PCM8S : RS_PCM8U;
+-			ReadSample(psmp, smptype, (LPCSTR)(lpStream+dwPos), dwMemLength - dwPos);
+-			nSmp++;
+-		} else
+-		{
+-			break;
+-		}
+-	}
+-	return TRUE;
+-}
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_far.cxx audacious-plugins-2.5.4/src/modplug/load_far.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_far.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_far.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,271 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-////////////////////////////////////////
+-// Farandole (FAR) module loader	  //
+-////////////////////////////////////////
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#pragma warning(disable:4244)
+-
+-#define FARFILEMAGIC	0xFE524146	// "FAR"
+-
+-#pragma pack(1)
+-
+-typedef struct FARHEADER1
+-{
+-	DWORD id;				// file magic FAR=
+-	CHAR songname[40];		// songname
+-	CHAR magic2[3];			// 13,10,26
+-	WORD headerlen;			// remaining length of header in bytes
+-	BYTE version;			// 0xD1
+-	BYTE onoff[16];
+-	BYTE edit1[9];
+-	BYTE speed;
+-	BYTE panning[16];
+-	BYTE edit2[4];
+-	WORD stlen;
+-} FARHEADER1;
+-
+-typedef struct FARHEADER2
+-{
+-	BYTE orders[256];
+-	BYTE numpat;
+-	BYTE snglen;
+-	BYTE loopto;
+-	WORD patsiz[256];
+-} FARHEADER2;
+-
+-typedef struct FARSAMPLE
+-{
+-	CHAR samplename[32];
+-	DWORD length;
+-	BYTE finetune;
+-	BYTE volume;
+-	DWORD reppos;
+-	DWORD repend;
+-	BYTE type;
+-	BYTE loop;
+-} FARSAMPLE;
+-
+-#pragma pack()
+-
+-
+-BOOL CSoundFile::ReadFAR(const BYTE *lpStream, DWORD dwMemLength)
+-//---------------------------------------------------------------
+-{
+-	FARHEADER1 *pmh1 = (FARHEADER1 *)lpStream;
+-	FARHEADER2 *pmh2;
+-	DWORD dwMemPos = sizeof(FARHEADER1);
+-	UINT headerlen;
+-	BYTE samplemap[8];
+-
+-	if ((!lpStream) || (dwMemLength < 1024) || (bswapLE32(pmh1->id) != FARFILEMAGIC)
+-	 || (pmh1->magic2[0] != 13) || (pmh1->magic2[1] != 10) || (pmh1->magic2[2] != 26)) return FALSE;
+-	headerlen = bswapLE16(pmh1->headerlen);
+-	pmh1->stlen = bswapLE16( pmh1->stlen ); /* inplace byteswap -- Toad */
+-	if ((headerlen >= dwMemLength) || (dwMemPos + pmh1->stlen + sizeof(FARHEADER2) >= dwMemLength)) return FALSE;
+-	// Globals
+-	m_nType = MOD_TYPE_FAR;
+-	m_nChannels = 16;
+-	m_nInstruments = 0;
+-	m_nSamples = 0;
+-	m_nSongPreAmp = 0x20;
+-	m_nDefaultSpeed = pmh1->speed;
+-	m_nDefaultTempo = 80;
+-	m_nDefaultGlobalVolume = 256;
+-
+-	memcpy(m_szNames[0], pmh1->songname, 32);
+-	// Channel Setting
+-	for (UINT nchpan=0; nchpan<16; nchpan++)
+-	{
+-		ChnSettings[nchpan].dwFlags = 0;
+-		ChnSettings[nchpan].nPan = ((pmh1->panning[nchpan] & 0x0F) << 4) + 8;
+-		ChnSettings[nchpan].nVolume = 64;
+-	}
+-	// Reading comment
+-	if (pmh1->stlen)
+-	{
+-		UINT szLen = pmh1->stlen;
+-		if (szLen > dwMemLength - dwMemPos) szLen = dwMemLength - dwMemPos;
+-		if ((m_lpszSongComments = new char[szLen + 1]) != NULL)
+-		{
+-			memcpy(m_lpszSongComments, lpStream+dwMemPos, szLen);
+-			m_lpszSongComments[szLen] = 0;
+-		}
+-		dwMemPos += pmh1->stlen;
+-	}
+-	// Reading orders
+-	pmh2 = (FARHEADER2 *)(lpStream + dwMemPos);
+-	dwMemPos += sizeof(FARHEADER2);
+-	if (dwMemPos >= dwMemLength) return TRUE;
+-	for (UINT iorder=0; iorder<MAX_ORDERS; iorder++)
+-	{
+-		Order[iorder] = (iorder <= pmh2->snglen) ? pmh2->orders[iorder] : 0xFF;
+-	}
+-	m_nRestartPos = pmh2->loopto;
+-	// Reading Patterns	
+-	dwMemPos += headerlen - (869 + pmh1->stlen);
+-	if (dwMemPos >= dwMemLength) return TRUE;
+-
+-	// byteswap pattern data -- Toad
+-	UINT psfix = 0 ;
+-	while( psfix++ < 256 )
+-	{
+-		pmh2->patsiz[psfix] = bswapLE16( pmh2->patsiz[psfix] ) ;
+-	}
+-	// end byteswap of pattern data
+-
+-	WORD *patsiz = (WORD *)pmh2->patsiz;
+-	for (UINT ipat=0; ipat<256; ipat++) if (patsiz[ipat])
+-	{
+-		UINT patlen = patsiz[ipat];
+-		if ((ipat >= MAX_PATTERNS) || (patsiz[ipat] < 2))
+-		{
+-			dwMemPos += patlen;
+-			continue;
+-		}
+-		if (dwMemPos + patlen >= dwMemLength) return TRUE;
+-		UINT rows = (patlen - 2) >> 6;
+-		if (!rows)
+-		{
+-			dwMemPos += patlen;
+-			continue;
+-		}
+-		if (rows > 256) rows = 256;
+-		if (rows < 16) rows = 16;
+-		PatternSize[ipat] = rows;
+-		PatternAllocSize[ipat] = rows;
+-		if ((Patterns[ipat] = AllocatePattern(rows, m_nChannels)) == NULL) return TRUE;
+-		MODCOMMAND *m = Patterns[ipat];
+-		UINT patbrk = lpStream[dwMemPos];
+-		const BYTE *p = lpStream + dwMemPos + 2;
+-		UINT max = rows*16*4;
+-		if (max > patlen-2) max = patlen-2;
+-		for (UINT len=0; len<max; len += 4, m++)
+-		{
+-			BYTE note = p[len];
+-			BYTE ins = p[len+1];
+-			BYTE vol = p[len+2];
+-			BYTE eff = p[len+3];
+-			if (note)
+-			{
+-				m->instr = ins + 1;
+-				m->note = note + 36;
+-			}
+-			if (vol & 0x0F)
+-			{
+-				m->volcmd = VOLCMD_VOLUME;
+-				m->vol = (vol & 0x0F) << 2;
+-				if (m->vol <= 4) m->vol = 0;
+-			}
+-			switch(eff & 0xF0)
+-			{
+-			// 1.x: Portamento Up
+-			case 0x10:
+-				m->command = CMD_PORTAMENTOUP;
+-				m->param = eff & 0x0F;
+-				break;
+-			// 2.x: Portamento Down
+-			case 0x20:
+-				m->command = CMD_PORTAMENTODOWN;
+-				m->param = eff & 0x0F;
+-				break;
+-			// 3.x: Tone-Portamento
+-			case 0x30:
+-				m->command = CMD_TONEPORTAMENTO;
+-				m->param = (eff & 0x0F) << 2;
+-				break;
+-			// 4.x: Retrigger
+-			case 0x40:
+-				m->command = CMD_RETRIG;
+-				m->param = 6 / (1+(eff&0x0F)) + 1;
+-				break;
+-			// 5.x: Set Vibrato Depth
+-			case 0x50:
+-				m->command = CMD_VIBRATO;
+-				m->param = (eff & 0x0F);
+-				break;
+-			// 6.x: Set Vibrato Speed
+-			case 0x60:
+-				m->command = CMD_VIBRATO;
+-				m->param = (eff & 0x0F) << 4;
+-				break;
+-			// 7.x: Vol Slide Up
+-			case 0x70:
+-				m->command = CMD_VOLUMESLIDE;
+-				m->param = (eff & 0x0F) << 4;
+-				break;
+-			// 8.x: Vol Slide Down
+-			case 0x80:
+-				m->command = CMD_VOLUMESLIDE;
+-				m->param = (eff & 0x0F);
+-				break;
+-			// A.x: Port to vol
+-			case 0xA0:
+-				m->volcmd = VOLCMD_VOLUME;
+-				m->vol = ((eff & 0x0F) << 2) + 4;
+-				break;
+-			// B.x: Set Balance
+-			case 0xB0:
+-				m->command = CMD_PANNING8;
+-				m->param = (eff & 0x0F) << 4;
+-				break;
+-			// F.x: Set Speed
+-			case 0xF0:
+-				m->command = CMD_SPEED;
+-				m->param = eff & 0x0F;
+-				break;
+-			default:
+-				if ((patbrk) &&	(patbrk+1 == (len >> 6)) && (patbrk+1 != rows-1))
+-				{
+-					m->command = CMD_PATTERNBREAK;
+-					patbrk = 0;
+-				}
+-			}
+-		}
+-		dwMemPos += patlen;
+-	}
+-	// Reading samples
+-	if (dwMemPos + 8 >= dwMemLength) return TRUE;
+-	memcpy(samplemap, lpStream+dwMemPos, 8);
+-	dwMemPos += 8;
+-	MODINSTRUMENT *pins = &Ins[1];
+-	for (UINT ismp=0; ismp<64; ismp++, pins++) if (samplemap[ismp >> 3] & (1 << (ismp & 7)))
+-	{
+-		if (dwMemPos + sizeof(FARSAMPLE) > dwMemLength) return TRUE;
+-		FARSAMPLE *pfs = (FARSAMPLE *)(lpStream + dwMemPos);
+-		dwMemPos += sizeof(FARSAMPLE);
+-		m_nSamples = ismp + 1;
+-		memcpy(m_szNames[ismp+1], pfs->samplename, 32);
+-		pfs->length = bswapLE32( pfs->length ) ; /* endian fix - Toad */
+-		pins->nLength = pfs->length ;
+-		pins->nLoopStart = bswapLE32(pfs->reppos) ;
+-		pins->nLoopEnd = bswapLE32(pfs->repend) ;
+-		pins->nFineTune = 0;
+-		pins->nC4Speed = 8363*2;
+-		pins->nGlobalVol = 64;
+-		pins->nVolume = pfs->volume << 4;
+-		pins->uFlags = 0;
+-		if ((pins->nLength > 3) && (dwMemPos + 4 < dwMemLength))
+-		{
+-			if (pfs->type & 1)
+-			{
+-				pins->uFlags |= CHN_16BIT;
+-				pins->nLength >>= 1;
+-				pins->nLoopStart >>= 1;
+-				pins->nLoopEnd >>= 1;
+-			}
+-			if ((pfs->loop & 8) && (pins->nLoopEnd > 4)) pins->uFlags |= CHN_LOOP;
+-			ReadSample(pins, (pins->uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S,
+-						(LPSTR)(lpStream+dwMemPos), dwMemLength - dwMemPos);
+-		}
+-		dwMemPos += pfs->length;
+-	}
+-	return TRUE;
+-}
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_it.cxx audacious-plugins-2.5.4/src/modplug/load_it.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_it.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_it.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,975 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>,
+- *          Adam Goode       <adam at evdebs.org> (endian and char fixes for PPC)
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-#include "it_defs.h"
+-
+-/* blah, -mrsb.
+-this is a schism header */
+-#include "midi.h"
+-
+-#ifdef MSC_VER
+-#pragma warning(disable:4244)
+-#endif
+-
+-BYTE autovibit2xm[8] =
+-{ 0, 3, 1, 4, 2, 0, 0, 0 };
+-
+-BYTE autovibxm2it[8] =
+-{ 0, 2, 4, 1, 3, 0, 0, 0 };
+-
+-//////////////////////////////////////////////////////////
+-// Impulse Tracker IT file support (import only)
+-
+-
+-static inline UINT ConvertVolParam(UINT value)
+-//--------------------------------------------
+-{
+-	return (value > 9)  ? 9 : value;
+-}
+-
+-
+-BOOL CSoundFile::ITInstrToMPT(const void *p, INSTRUMENTHEADER *penv, UINT trkvers)
+-//--------------------------------------------------------------------------------
+-{
+-	if (trkvers < 0x0200)
+-	{
+-		const ITOLDINSTRUMENT *pis = (const ITOLDINSTRUMENT *)p;
+-		memcpy(penv->name, pis->name, 26);
+-		memcpy(penv->filename, pis->filename, 12);
+-		penv->nFadeOut = bswapLE16(pis->fadeout) << 6;
+-		penv->nGlobalVol = 128;
+-		for (UINT j=0; j<120; j++)
+-		{
+-			UINT note = pis->keyboard[j*2];
+-			UINT ins = pis->keyboard[j*2+1];
+-			if (ins < MAX_SAMPLES) penv->Keyboard[j] = ins;
+-			if (note < 128) penv->NoteMap[j] = note+1;
+-			else if (note >= 0xFE) penv->NoteMap[j] = note;
+-		}
+-		if (pis->flags & 0x01) penv->dwFlags |= ENV_VOLUME;
+-		if (pis->flags & 0x02) penv->dwFlags |= ENV_VOLLOOP;
+-		if (pis->flags & 0x04) penv->dwFlags |= ENV_VOLSUSTAIN;
+-		penv->VolEnv.nLoopStart = pis->vls;
+-		penv->VolEnv.nLoopEnd = pis->vle;
+-		penv->VolEnv.nSustainStart = pis->sls;
+-		penv->VolEnv.nSustainEnd = pis->sle;
+-		penv->VolEnv.nNodes = 25;
+-		for (UINT ev=0; ev<25; ev++)
+-		{
+-			if ((penv->VolEnv.Ticks[ev] = pis->nodes[ev*2]) == 0xFF)
+-			{
+-				penv->VolEnv.nNodes = ev;
+-				break;
+-			}
+-			penv->VolEnv.Values[ev] = pis->nodes[ev*2+1];
+-		}
+-		penv->nNNA = pis->nna;
+-		penv->nDCT = pis->dnc;
+-		penv->nPan = 0x80;
+-	} else
+-	{
+-		const ITINSTRUMENT *pis = (const ITINSTRUMENT *)p;
+-		memcpy(penv->name, pis->name, 26);
+-		memcpy(penv->filename, pis->filename, 12);
+-		penv->nMidiProgram = pis->mpr;
+-		penv->nMidiChannel = pis->mch;
+-		penv->wMidiBank = bswapLE16(pis->mbank);
+-		penv->nFadeOut = bswapLE16(pis->fadeout) << 5;
+-		penv->nGlobalVol = pis->gbv;
+-		if (penv->nGlobalVol > 128) penv->nGlobalVol = 128;
+-		for (UINT j=0; j<120; j++)
+-		{
+-			UINT note = pis->keyboard[j*2];
+-			UINT ins = pis->keyboard[j*2+1];
+-			if (ins < MAX_SAMPLES) penv->Keyboard[j] = ins;
+-			if (note < 128) penv->NoteMap[j] = note+1;
+-			else if (note >= 0xFE) penv->NoteMap[j] = note;
+-		}
+-		// Volume Envelope
+-		if (pis->volenv.flags & 1) penv->dwFlags |= ENV_VOLUME;
+-		if (pis->volenv.flags & 2) penv->dwFlags |= ENV_VOLLOOP;
+-		if (pis->volenv.flags & 4) penv->dwFlags |= ENV_VOLSUSTAIN;
+-		if (pis->volenv.flags & 8) penv->dwFlags |= ENV_VOLCARRY;
+-		penv->VolEnv.nNodes = pis->volenv.num;
+-		if (penv->VolEnv.nNodes > 25) penv->VolEnv.nNodes = 25;
+-
+-		penv->VolEnv.nLoopStart = pis->volenv.lpb;
+-		penv->VolEnv.nLoopEnd = pis->volenv.lpe;
+-		penv->VolEnv.nSustainStart = pis->volenv.slb;
+-		penv->VolEnv.nSustainEnd = pis->volenv.sle;
+-		// Panning Envelope
+-		if (pis->panenv.flags & 1) penv->dwFlags |= ENV_PANNING;
+-		if (pis->panenv.flags & 2) penv->dwFlags |= ENV_PANLOOP;
+-		if (pis->panenv.flags & 4) penv->dwFlags |= ENV_PANSUSTAIN;
+-		if (pis->panenv.flags & 8) penv->dwFlags |= ENV_PANCARRY;
+-		penv->PanEnv.nNodes = pis->panenv.num;
+-		if (penv->PanEnv.nNodes > 25) penv->PanEnv.nNodes = 25;
+-		penv->PanEnv.nLoopStart = pis->panenv.lpb;
+-		penv->PanEnv.nLoopEnd = pis->panenv.lpe;
+-		penv->PanEnv.nSustainStart = pis->panenv.slb;
+-		penv->PanEnv.nSustainEnd = pis->panenv.sle;
+-		// Pitch Envelope
+-		if (pis->pitchenv.flags & 1) penv->dwFlags |= ENV_PITCH;
+-		if (pis->pitchenv.flags & 2) penv->dwFlags |= ENV_PITCHLOOP;
+-		if (pis->pitchenv.flags & 4) penv->dwFlags |= ENV_PITCHSUSTAIN;
+-		if (pis->pitchenv.flags & 8) penv->dwFlags |= ENV_PITCHCARRY;
+-		if (pis->pitchenv.flags & 0x80) penv->dwFlags |= ENV_FILTER;
+-		penv->PitchEnv.nNodes = pis->pitchenv.num;
+-		if (penv->PitchEnv.nNodes > 25) penv->PitchEnv.nNodes = 25;
+-		penv->PitchEnv.nLoopStart = pis->pitchenv.lpb;
+-		penv->PitchEnv.nLoopEnd = pis->pitchenv.lpe;
+-		penv->PitchEnv.nSustainStart = pis->pitchenv.slb;
+-		penv->PitchEnv.nSustainEnd = pis->pitchenv.sle;
+-		// Envelopes Data
+-		for (UINT ev=0; ev<25; ev++)
+-		{
+-			penv->VolEnv.Values[ev] = pis->volenv.data[ev*3];
+-			penv->VolEnv.Ticks[ev] = (pis->volenv.data[ev*3+2] << 8) | (pis->volenv.data[ev*3+1]);
+-			penv->PanEnv.Values[ev] = pis->panenv.data[ev*3] + 32;
+-			penv->PanEnv.Ticks[ev] = (pis->panenv.data[ev*3+2] << 8) | (pis->panenv.data[ev*3+1]);
+-			penv->PitchEnv.Values[ev] = pis->pitchenv.data[ev*3] + 32;
+-			penv->PitchEnv.Ticks[ev] = (pis->pitchenv.data[ev*3+2] << 8) | (pis->pitchenv.data[ev*3+1]);
+-		}
+-		penv->nNNA = pis->nna % 4;
+-		penv->nDCT = pis->dct % 4;
+-		penv->nDNA = pis->dca % 3;
+-		penv->nPPS = pis->pps;
+-		penv->nPPC = pis->ppc;
+-		penv->nIFC = pis->ifc;
+-		penv->nIFR = pis->ifr;
+-		penv->nVolSwing = pis->rv;
+-		penv->nPanSwing = pis->rp;
+-		penv->nPan = (pis->dfp & 0x7F) << 2;
+-		if (penv->nPan > 256) penv->nPan = 128;
+-		if (pis->dfp < 0x80) penv->dwFlags |= ENV_SETPANNING;
+-	}
+-	if ((penv->VolEnv.nLoopStart >= 25) || (penv->VolEnv.nLoopEnd >= 25)) penv->dwFlags &= ~ENV_VOLLOOP;
+-	if ((penv->VolEnv.nSustainStart >= 25) || (penv->VolEnv.nSustainEnd >= 25)) penv->dwFlags &= ~ENV_VOLSUSTAIN;
+-	return TRUE;
+-}
+-
+-
+-BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength)
+-//--------------------------------------------------------------
+-{
+-	ITFILEHEADER pifh = *(ITFILEHEADER *)lpStream;
+-	DWORD dwMemPos = sizeof(ITFILEHEADER);
+-	DWORD inspos[MAX_INSTRUMENTS];
+-	DWORD smppos[MAX_SAMPLES];
+-	DWORD patpos[MAX_PATTERNS];
+-	BYTE chnmask[64];
+-	MODCOMMAND lastvalue[64];
+-
+-	if ((!lpStream) || (dwMemLength < 0xc2)) return FALSE;
+-
+-	pifh.id = bswapLE32(pifh.id);
+-	if (pifh.id == 0x49504D49) {
+-		if (dwMemLength < 554) return FALSE;
+-
+-		WORD tv;
+-		INSTRUMENTHEADER *zenv = new INSTRUMENTHEADER;
+-		if (!zenv) return FALSE;
+-		memset(zenv, 0, sizeof(INSTRUMENTHEADER));
+-		memcpy(&tv, lpStream+0x1C, 2); /* trkvers */
+-		if (!ITInstrToMPT(lpStream, zenv, tv)) {
+-			delete zenv;
+-			return FALSE;
+-		}
+-
+-		/* okay, we need samples now */
+-		unsigned int q = 554;
+-		BYTE expect_samples = lpStream[0x1E];
+-
+-		m_nType = MOD_TYPE_IT;
+-		m_nInstruments = 1;
+-		m_nSamples = expect_samples;
+-		m_dwSongFlags = SONG_INSTRUMENTMODE | SONG_LINEARSLIDES /* eh? */;
+-
+-		memcpy(m_szNames[0], lpStream + 0x20, 26);
+-		m_szNames[0][26] = 0;
+-
+-		if (q+(80*expect_samples) >= dwMemLength) {
+-			delete zenv;
+-			return FALSE;
+-		}
+-
+-		for (UINT nsmp = 0; nsmp < expect_samples; nsmp++) {
+-
+-			ITSAMPLESTRUCT pis = *(ITSAMPLESTRUCT *)(lpStream+q);
+-			q += 80; /* length of ITS header */
+-
+-			pis.id = bswapLE32(pis.id);
+-			pis.length = bswapLE32(pis.length);
+-			pis.loopbegin = bswapLE32(pis.loopbegin);
+-			pis.loopend = bswapLE32(pis.loopend);
+-			pis.C5Speed = bswapLE32(pis.C5Speed);
+-			pis.susloopbegin = bswapLE32(pis.susloopbegin);
+-			pis.susloopend = bswapLE32(pis.susloopend);
+-			pis.samplepointer = bswapLE32(pis.samplepointer);
+-	
+-			if (pis.id == 0x53504D49)
+-			{
+-				MODINSTRUMENT *pins = &Ins[nsmp+1];
+-				memcpy(pins->name, pis.filename, 12);
+-				pins->uFlags = 0;
+-				pins->nLength = 0;
+-				pins->nLoopStart = pis.loopbegin;
+-				pins->nLoopEnd = pis.loopend;
+-				pins->nSustainStart = pis.susloopbegin;
+-				pins->nSustainEnd = pis.susloopend;
+-				pins->nC4Speed = pis.C5Speed;
+-				if (!pins->nC4Speed) pins->nC4Speed = 8363;
+-				//if (pis.C5Speed < 256) pins->nC4Speed = 256;
+-				pins->nVolume = pis.vol << 2;
+-				if (pins->nVolume > 256) pins->nVolume = 256;
+-				pins->nGlobalVol = pis.gvl;
+-				if (pins->nGlobalVol > 64) pins->nGlobalVol = 64;
+-				if (pis.flags & 0x10) pins->uFlags |= CHN_LOOP;
+-				if (pis.flags & 0x20) pins->uFlags |= CHN_SUSTAINLOOP;
+-				if (pis.flags & 0x40) pins->uFlags |= CHN_PINGPONGLOOP;
+-				if (pis.flags & 0x80) pins->uFlags |= CHN_PINGPONGSUSTAIN;
+-				pins->nPan = (pis.dfp & 0x7F) << 2;
+-				if (pins->nPan > 256) pins->nPan = 256;
+-				if (pis.dfp & 0x80) pins->uFlags |= CHN_PANNING;
+-				pins->nVibType = autovibit2xm[pis.vit & 7];
+-				pins->nVibRate = pis.vis;
+-				pins->nVibDepth = pis.vid & 0x7F;
+-				pins->nVibSweep = pis.vir;
+-				if ((pis.samplepointer) && (pis.samplepointer < dwMemLength) && (pis.length))
+-				{
+-					pins->nLength = pis.length;
+-					if (pins->nLength > MAX_SAMPLE_LENGTH) pins->nLength = MAX_SAMPLE_LENGTH;
+-					UINT flags = (pis.cvt & 1) ? RS_PCM8S : RS_PCM8U;
+-					if (pis.flags & 2)
+-					{
+-						flags += 5;
+-						if (pis.flags & 4) flags |= RSF_STEREO;
+-						pins->uFlags |= CHN_16BIT;
+-						// IT 2.14 16-bit packed sample ?
+-						if (pis.flags & 8) flags = ((pifh.cmwt >= 0x215) && (pis.cvt & 4)) ? RS_IT21516 : RS_IT21416;
+-					} else
+-					{
+-						if (pis.flags & 4) flags |= RSF_STEREO;
+-						if (pis.cvt == 0xFF) flags = RS_ADPCM4; else
+-						// IT 2.14 8-bit packed sample ?
+-						if (pis.flags & 8)	flags =	((pifh.cmwt >= 0x215) && (pis.cvt & 4)) ? RS_IT2158 : RS_IT2148;
+-					}
+-					ReadSample(&Ins[nsmp+1], flags, (LPSTR)(lpStream+pis.samplepointer), dwMemLength - pis.samplepointer);
+-				}
+-			}
+-			memcpy(m_szNames[nsmp+1], pis.name, 26);
+-			
+-		}
+-
+-		Headers[1] = zenv;
+-		return TRUE;
+-	}
+-
+-
+-	pifh.ordnum = bswapLE16(pifh.ordnum);
+-	pifh.insnum = bswapLE16(pifh.insnum);
+-	pifh.smpnum = bswapLE16(pifh.smpnum);
+-	pifh.patnum = bswapLE16(pifh.patnum);
+-	pifh.cwtv = bswapLE16(pifh.cwtv);
+-	pifh.cmwt = bswapLE16(pifh.cmwt);
+-	pifh.flags = bswapLE16(pifh.flags);
+-	pifh.special = bswapLE16(pifh.special);
+-	pifh.msglength = bswapLE16(pifh.msglength);
+-	pifh.msgoffset = bswapLE32(pifh.msgoffset);
+-	pifh.reserved2 = bswapLE32(pifh.reserved2);
+-
+-
+-
+-	if ((pifh.id != 0x4D504D49) || (pifh.insnum >= MAX_INSTRUMENTS)
+-	 || (pifh.smpnum >= MAX_INSTRUMENTS)) return FALSE;
+-	if (dwMemPos + pifh.ordnum + pifh.insnum*4
+-	 + pifh.smpnum*4 + pifh.patnum*4 > dwMemLength) return FALSE;
+-	m_nType = MOD_TYPE_IT;
+-	if (!(pifh.flags & 0x01)) m_dwSongFlags |= SONG_NOSTEREO;
+-	if (pifh.flags & 0x04) m_dwSongFlags |= SONG_INSTRUMENTMODE;
+-	if (pifh.flags & 0x08) m_dwSongFlags |= SONG_LINEARSLIDES;
+-	if (pifh.flags & 0x10) m_dwSongFlags |= SONG_ITOLDEFFECTS;
+-	if (pifh.flags & 0x20) m_dwSongFlags |= SONG_ITCOMPATMODE;
+-	if (pifh.flags & 0x40) {
+-		midi_flags |= MIDI_PITCH_BEND;
+-		midi_pitch_depth = pifh.pwd;
+-	}
+-	if (pifh.flags & 0x80) m_dwSongFlags |= SONG_EMBEDMIDICFG;
+-	if (pifh.flags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE;
+-	memcpy(m_szNames[0], pifh.songname, 26);
+-	m_szNames[0][26] = 0;
+-	if (pifh.cwtv >= 0x0213) {
+-		m_rowHighlightMinor = pifh.hilight_minor;
+-		m_rowHighlightMajor = pifh.hilight_major;
+-	} else {
+-		m_rowHighlightMinor = 4;
+-		m_rowHighlightMajor = 16;
+-	}
+-	// Global Volume
+-        m_nDefaultGlobalVolume = pifh.globalvol << 1;
+-        if (m_nDefaultGlobalVolume > 256) m_nDefaultGlobalVolume = 256;
+-	if (pifh.speed) m_nDefaultSpeed = pifh.speed;
+-	if (pifh.tempo) m_nDefaultTempo = pifh.tempo;
+-	m_nSongPreAmp = pifh.mv;
+-        if (m_nSongPreAmp > 128)
+-                m_nSongPreAmp = 128;
+-	m_nStereoSeparation = pifh.sep;
+-	// Reading Channels Pan Positions
+-	for (int ipan=0; ipan<64; ipan++) if (pifh.chnpan[ipan] != 0xFF)
+-	{
+-		ChnSettings[ipan].nVolume = pifh.chnvol[ipan];
+-		ChnSettings[ipan].nPan = 128;
+-		if (pifh.chnpan[ipan] & 0x80) ChnSettings[ipan].dwFlags |= CHN_MUTE;
+-		UINT n = pifh.chnpan[ipan] & 0x7F;
+-		if (n <= 64) ChnSettings[ipan].nPan = n << 2;
+-		if (n == 100) ChnSettings[ipan].dwFlags |= CHN_SURROUND;
+-	}
+-	if (m_nChannels < 4) m_nChannels = 4;
+-	// Reading Song Message
+-	if ((pifh.special & 0x01) && (pifh.msglength) && (pifh.msgoffset + pifh.msglength < dwMemLength))
+-	{
+-		m_lpszSongComments = new char[pifh.msglength+1];
+-		if (m_lpszSongComments)
+-		{
+-			memcpy(m_lpszSongComments, lpStream+pifh.msgoffset, pifh.msglength);
+-			m_lpszSongComments[pifh.msglength] = 0;
+-		}
+-	}
+-	// Reading orders
+-	UINT nordsize = pifh.ordnum;
+-	if (nordsize > MAX_ORDERS) nordsize = MAX_ORDERS;
+-	memcpy(Order, lpStream+dwMemPos, nordsize);
+-
+-	dwMemPos += pifh.ordnum;
+-	// Reading Instrument Offsets
+-	memset(inspos, 0, sizeof(inspos));
+-	UINT inspossize = pifh.insnum;
+-	if (inspossize > MAX_INSTRUMENTS) inspossize = MAX_INSTRUMENTS;
+-	inspossize <<= 2;
+-	memcpy(inspos, lpStream+dwMemPos, inspossize);
+-	for (UINT j=0; j < (inspossize>>2); j++)
+-	{
+-	       inspos[j] = bswapLE32(inspos[j]);
+-	}
+-	dwMemPos += pifh.insnum * 4;
+-	// Reading Samples Offsets
+-	memset(smppos, 0, sizeof(smppos));
+-	UINT smppossize = pifh.smpnum;
+-	if (smppossize > MAX_SAMPLES) smppossize = MAX_SAMPLES;
+-	smppossize <<= 2;
+-	memcpy(smppos, lpStream+dwMemPos, smppossize);
+-	for (UINT j=0; j < (smppossize>>2); j++)
+-	{
+-	       smppos[j] = bswapLE32(smppos[j]);
+-	}
+-	dwMemPos += pifh.smpnum * 4;
+-	// Reading Patterns Offsets
+-	memset(patpos, 0, sizeof(patpos));
+-	UINT patpossize = pifh.patnum;
+-	if (patpossize > MAX_PATTERNS) patpossize = MAX_PATTERNS;
+-	patpossize <<= 2;
+-	memcpy(patpos, lpStream+dwMemPos, patpossize);
+-	for (UINT j=0; j < (patpossize>>2); j++)
+-	{
+-	       patpos[j] = bswapLE32(patpos[j]);
+-	}
+-	dwMemPos += pifh.patnum * 4;
+-
+-	for (UINT i = 0; i < pifh.ordnum; i++) {
+-		if (Order[i] >= pifh.patnum && Order[i] < MAX_PATTERNS) {
+-			pifh.patnum = Order[i];
+-			for (UINT j = patpossize; j < (unsigned)(pifh.patnum>>2); j++)
+-				patpos[j] = 0;
+-			patpossize = pifh.patnum;
+-		}
+-	}
+-
+-
+-	// Reading IT Extra Info
+-	if (dwMemPos + 2 < dwMemLength)
+-	{
+-		UINT nflt = bswapLE16(*((WORD *)(lpStream + dwMemPos)));
+-		dwMemPos += 2;
+-		if (dwMemPos + nflt * 8 < dwMemLength) dwMemPos += nflt * 8;
+-	}
+-	// Reading Midi Output & Macros
+-	if (m_dwSongFlags & SONG_EMBEDMIDICFG)
+-	{
+-		if (dwMemPos + sizeof(MODMIDICFG) < dwMemLength)
+-		{
+-			memcpy(&m_MidiCfg, lpStream+dwMemPos, sizeof(MODMIDICFG));
+-			dwMemPos += sizeof(MODMIDICFG);
+-		} else {
+-			ResetMidiCfg();
+-		}
+-	} else {
+-		ResetMidiCfg();
+-	}
+-#if 0
+-	// Read pattern names: "PNAM"
+-	if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e50))
+-	{
+-		UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4)));
+-		dwMemPos += 8;
+-		if ((dwMemPos + len <= dwMemLength) && (len <= MAX_PATTERNS*MAX_PATTERNNAME) && (len >= MAX_PATTERNNAME))
+-		{
+-			m_lpszPatternNames = new char[len];
+-			if (m_lpszPatternNames)
+-			{
+-				m_nPatternNames = len / MAX_PATTERNNAME;
+-				memcpy(m_lpszPatternNames, lpStream+dwMemPos, len);
+-			}
+-			dwMemPos += len;
+-		}
+-	}
+-#endif
+-	// 4-channels minimum
+-	m_nChannels = 4;
+-#if 0
+-	// Read channel names: "CNAM"
+-	if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e43))
+-	{
+-		UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4)));
+-		dwMemPos += 8;
+-		if ((dwMemPos + len <= dwMemLength) && (len <= 64*MAX_CHANNELNAME))
+-		{
+-			UINT n = len / MAX_CHANNELNAME;
+-			if (n > m_nChannels) m_nChannels = n;
+-			for (UINT i=0; i<n; i++)
+-			{
+-				memcpy(ChnSettings[i].szName, (lpStream+dwMemPos+i*MAX_CHANNELNAME), MAX_CHANNELNAME);
+-				ChnSettings[i].szName[MAX_CHANNELNAME-1] = 0;
+-			}
+-			dwMemPos += len;
+-		}
+-	}
+-	// Read mix plugins information
+-	if (dwMemPos + 8 < dwMemLength)
+-	{
+-		dwMemPos += LoadMixPlugins(lpStream+dwMemPos, dwMemLength-dwMemPos);
+-	}
+-#endif
+-	// Checking for unused channels
+-	UINT npatterns = pifh.patnum;
+-	if (npatterns > MAX_PATTERNS) npatterns = MAX_PATTERNS;
+-	for (UINT patchk=0; patchk<npatterns; patchk++)
+-	{
+-		memset(chnmask, 0, sizeof(chnmask));
+-		if ((!patpos[patchk]) || ((DWORD)patpos[patchk] + 4 >= dwMemLength)) continue;
+-		UINT len = bswapLE16(*((WORD *)(lpStream+patpos[patchk])));
+-		UINT rows = bswapLE16(*((WORD *)(lpStream+patpos[patchk]+2)));
+-		if ((rows < 4) || (rows > 256)) continue;
+-		if (patpos[patchk]+8+len > dwMemLength) continue;
+-		UINT i = 0;
+-		const BYTE *p = lpStream+patpos[patchk]+8;
+-		UINT nrow = 0;
+-		while (nrow<rows)
+-		{
+-			if (i >= len) break;
+-			BYTE b = p[i++];
+-			if (!b)
+-			{
+-				nrow++;
+-				continue;
+-			}
+-			UINT ch = b & 0x7F;
+-			if (ch) ch = (ch - 1) & 0x3F;
+-			if (b & 0x80)
+-			{
+-				if (i >= len) break;
+-				chnmask[ch] = p[i++];
+-			}
+-			// Channel used
+-			if (chnmask[ch] & 0x0F)
+-			{
+-				if ((ch >= m_nChannels) && (ch < 64)) m_nChannels = ch+1;
+-			}
+-			// Note
+-			if (chnmask[ch] & 1) i++;
+-			// Instrument
+-			if (chnmask[ch] & 2) i++;
+-			// Volume
+-			if (chnmask[ch] & 4) i++;
+-			// Effect
+-			if (chnmask[ch] & 8) i += 2;
+-			if (i >= len) break;
+-		}
+-	}
+-	// Reading Instruments
+-	m_nInstruments = pifh.insnum;
+-	if (m_nInstruments >= MAX_INSTRUMENTS) m_nInstruments = MAX_INSTRUMENTS-1;
+-	for (UINT nins=0; nins<m_nInstruments; nins++)
+-	{
+-		if ((inspos[nins] > 0) && (inspos[nins] < dwMemLength - sizeof(ITOLDINSTRUMENT)))
+-		{
+-			INSTRUMENTHEADER *penv = new INSTRUMENTHEADER;
+-			if (!penv) continue;
+-			Headers[nins+1] = penv;
+-			memset(penv, 0, sizeof(INSTRUMENTHEADER));
+-			ITInstrToMPT(lpStream + inspos[nins], penv, pifh.cmwt);
+-		}
+-	}
+-	// Reading Samples
+-	m_nSamples = pifh.smpnum;
+-	if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES-1;
+-	for (UINT nsmp=0; nsmp<pifh.smpnum; nsmp++) if ((smppos[nsmp]) && (smppos[nsmp] + sizeof(ITSAMPLESTRUCT) <= dwMemLength))
+-	{
+-		ITSAMPLESTRUCT pis = *(ITSAMPLESTRUCT *)(lpStream+smppos[nsmp]);
+-		pis.id = bswapLE32(pis.id);
+-		pis.length = bswapLE32(pis.length);
+-		pis.loopbegin = bswapLE32(pis.loopbegin);
+-		pis.loopend = bswapLE32(pis.loopend);
+-		pis.C5Speed = bswapLE32(pis.C5Speed);
+-		pis.susloopbegin = bswapLE32(pis.susloopbegin);
+-		pis.susloopend = bswapLE32(pis.susloopend);
+-		pis.samplepointer = bswapLE32(pis.samplepointer);
+-
+-		if (pis.id == 0x53504D49)
+-		{
+-			MODINSTRUMENT *pins = &Ins[nsmp+1];
+-			memcpy(pins->name, pis.filename, 12);
+-			pins->uFlags = 0;
+-			pins->nLength = 0;
+-			pins->nLoopStart = pis.loopbegin;
+-			pins->nLoopEnd = pis.loopend;
+-			pins->nSustainStart = pis.susloopbegin;
+-			pins->nSustainEnd = pis.susloopend;
+-			pins->nC4Speed = pis.C5Speed;
+-			if (!pins->nC4Speed) pins->nC4Speed = 8363;
+-			//if (pis.C5Speed < 256) pins->nC4Speed = 256;
+-			pins->nVolume = pis.vol << 2;
+-			if (pins->nVolume > 256) pins->nVolume = 256;
+-			pins->nGlobalVol = pis.gvl;
+-			if (pins->nGlobalVol > 64) pins->nGlobalVol = 64;
+-			if (pis.flags & 0x10) pins->uFlags |= CHN_LOOP;
+-			if (pis.flags & 0x20) pins->uFlags |= CHN_SUSTAINLOOP;
+-			if (pis.flags & 0x40) pins->uFlags |= CHN_PINGPONGLOOP;
+-			if (pis.flags & 0x80) pins->uFlags |= CHN_PINGPONGSUSTAIN;
+-			pins->nPan = (pis.dfp & 0x7F) << 2;
+-			if (pins->nPan > 256) pins->nPan = 256;
+-			if (pis.dfp & 0x80) pins->uFlags |= CHN_PANNING;
+-			pins->nVibType = autovibit2xm[pis.vit & 7];
+-			pins->nVibRate = pis.vis;
+-			pins->nVibDepth = pis.vid & 0x7F;
+-			pins->nVibSweep = pis.vir;
+-			if ((pis.samplepointer) && (pis.samplepointer < dwMemLength) && (pis.length))
+-			{
+-				pins->nLength = pis.length;
+-				if (pins->nLength > MAX_SAMPLE_LENGTH) pins->nLength = MAX_SAMPLE_LENGTH;
+-				UINT flags = (pis.cvt & 1) ? RS_PCM8S : RS_PCM8U;
+-				if (pis.flags & 2)
+-				{
+-					flags += 5;
+-					if (pis.flags & 4) flags |= RSF_STEREO;
+-					pins->uFlags |= CHN_16BIT;
+-					// IT 2.14 16-bit packed sample ?
+-					if (pis.flags & 8) flags = ((pifh.cmwt >= 0x215) && (pis.cvt & 4)) ? RS_IT21516 : RS_IT21416;
+-				} else
+-				{
+-					if (pis.flags & 4) flags |= RSF_STEREO;
+-					if (pis.cvt == 0xFF) flags = RS_ADPCM4; else
+-					// IT 2.14 8-bit packed sample ?
+-					if (pis.flags & 8)	flags =	((pifh.cmwt >= 0x215) && (pis.cvt & 4)) ? RS_IT2158 : RS_IT2148;
+-				}
+-				ReadSample(&Ins[nsmp+1], flags, (LPSTR)(lpStream+pis.samplepointer), dwMemLength - pis.samplepointer);
+-			}
+-		}
+-		memcpy(m_szNames[nsmp+1], pis.name, 26);
+-	}
+-	// Reading Patterns
+-	for (UINT npat=0; npat<npatterns; npat++)
+-	{
+-		if ((!patpos[npat]) || ((DWORD)patpos[npat] + 4 >= dwMemLength))
+-		{
+-			PatternSize[npat] = 64;
+-			PatternAllocSize[npat] = 64;
+-			Patterns[npat] = AllocatePattern(64, m_nChannels);
+-			continue;
+-		}
+-
+-		UINT len = bswapLE16(*((WORD *)(lpStream+patpos[npat])));
+-		UINT rows = bswapLE16(*((WORD *)(lpStream+patpos[npat]+2)));
+-		if ((rows < 4) || (rows > 256)) continue;
+-		if (patpos[npat]+8+len > dwMemLength) continue;
+-		PatternSize[npat] = rows;
+-		PatternAllocSize[npat] = rows;
+-		if ((Patterns[npat] = AllocatePattern(rows, m_nChannels)) == NULL) continue;
+-		memset(lastvalue, 0, sizeof(lastvalue));
+-		memset(chnmask, 0, sizeof(chnmask));
+-		MODCOMMAND *m = Patterns[npat];
+-		UINT i = 0;
+-		const BYTE *p = lpStream+patpos[npat]+8;
+-		UINT nrow = 0;
+-		while (nrow<rows)
+-		{
+-			if (i >= len) break;
+-			BYTE b = p[i++];
+-			if (!b)
+-			{
+-				nrow++;
+-				m+=m_nChannels;
+-				continue;
+-			}
+-			UINT ch = b & 0x7F;
+-			if (ch) ch = (ch - 1) & 0x3F;
+-			if (b & 0x80)
+-			{
+-				if (i >= len) break;
+-				chnmask[ch] = p[i++];
+-			}
+-			if ((chnmask[ch] & 0x10) && (ch < m_nChannels))
+-			{
+-				m[ch].note = lastvalue[ch].note;
+-			}
+-			if ((chnmask[ch] & 0x20) && (ch < m_nChannels))
+-			{
+-				m[ch].instr = lastvalue[ch].instr;
+-			}
+-			if ((chnmask[ch] & 0x40) && (ch < m_nChannels))
+-			{
+-				m[ch].volcmd = lastvalue[ch].volcmd;
+-				m[ch].vol = lastvalue[ch].vol;
+-			}
+-			if ((chnmask[ch] & 0x80) && (ch < m_nChannels))
+-			{
+-				m[ch].command = lastvalue[ch].command;
+-				m[ch].param = lastvalue[ch].param;
+-			}
+-			if (chnmask[ch] & 1)	// Note
+-			{
+-				if (i >= len) break;
+-				UINT note = p[i++];
+-				if (ch < m_nChannels)
+-				{
+-					if (note < 0x80) note++;
+-					m[ch].note = note;
+-					lastvalue[ch].note = note;
+-				}
+-			}
+-			if (chnmask[ch] & 2)
+-			{
+-				if (i >= len) break;
+-				UINT instr = p[i++];
+-				if (ch < m_nChannels)
+-				{
+-					m[ch].instr = instr;
+-					lastvalue[ch].instr = instr;
+-				}
+-			}
+-			if (chnmask[ch] & 4)
+-			{
+-				if (i >= len) break;
+-				UINT vol = p[i++];
+-				if (ch < m_nChannels)
+-				{
+-					// 0-64: Set Volume
+-					if (vol <= 64) { m[ch].volcmd = VOLCMD_VOLUME; m[ch].vol = vol; } else
+-					// 128-192: Set Panning
+-					if ((vol >= 128) && (vol <= 192)) { m[ch].volcmd = VOLCMD_PANNING; m[ch].vol = vol - 128; } else
+-					// 65-74: Fine Volume Up
+-					if (vol < 75) { m[ch].volcmd = VOLCMD_FINEVOLUP; m[ch].vol = vol - 65; } else
+-					// 75-84: Fine Volume Down
+-					if (vol < 85) { m[ch].volcmd = VOLCMD_FINEVOLDOWN; m[ch].vol = vol - 75; } else
+-					// 85-94: Volume Slide Up
+-					if (vol < 95) { m[ch].volcmd = VOLCMD_VOLSLIDEUP; m[ch].vol = vol - 85; } else
+-					// 95-104: Volume Slide Down
+-					if (vol < 105) { m[ch].volcmd = VOLCMD_VOLSLIDEDOWN; m[ch].vol = vol - 95; } else
+-					// 105-114: Pitch Slide Up
+-					if (vol < 115) { m[ch].volcmd = VOLCMD_PORTADOWN; m[ch].vol = vol - 105; } else
+-					// 115-124: Pitch Slide Down
+-					if (vol < 125) { m[ch].volcmd = VOLCMD_PORTAUP; m[ch].vol = vol - 115; } else
+-					// 193-202: Portamento To
+-					if ((vol >= 193) && (vol <= 202)) { m[ch].volcmd = VOLCMD_TONEPORTAMENTO; m[ch].vol = vol - 193; } else
+-					// 203-212: Vibrato
+-					if ((vol >= 203) && (vol <= 212)) { m[ch].volcmd = VOLCMD_VIBRATO; m[ch].vol = vol - 203; }
+-					lastvalue[ch].volcmd = m[ch].volcmd;
+-					lastvalue[ch].vol = m[ch].vol;
+-				}
+-			}
+-			// Reading command/param
+-			if (chnmask[ch] & 8)
+-			{
+-				if (i > len - 2) break;
+-				UINT cmd = p[i++];
+-				UINT param = p[i++];
+-				if (ch < m_nChannels)
+-				{
+-					if (cmd)
+-					{
+-						m[ch].command = cmd;
+-						m[ch].param = param;
+-						S3MConvert(&m[ch], TRUE);
+-						lastvalue[ch].command = m[ch].command;
+-						lastvalue[ch].param = m[ch].param;
+-					}
+-				}
+-			}
+-		}
+-	}
+-	for (UINT ncu=0; ncu<MAX_BASECHANNELS; ncu++)
+-	{
+-		if (ncu>=m_nChannels)
+-		{
+-			ChnSettings[ncu].nVolume = 64;
+-			ChnSettings[ncu].dwFlags &= ~CHN_MUTE;
+-		}
+-	}
+-	m_nMinPeriod = 8;
+-	m_nMaxPeriod = 0xF000;
+-	return TRUE;
+-}
+-
+-
+-//////////////////////////////////////////////////////////////////////////////
+-// IT 2.14 compression
+-
+-DWORD ITReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n)
+-//-----------------------------------------------------------------
+-{
+-	DWORD retval = 0;
+-	UINT i = n;
+-
+-	if (n > 0)
+-	{
+-		do
+-		{
+-			if (!bitnum)
+-			{
+-				bitbuf = *ibuf++;
+-				bitnum = 8;
+-			}
+-			retval >>= 1;
+-			retval |= bitbuf << 31;
+-			bitbuf >>= 1;
+-			bitnum--;
+-			i--;
+-		} while (i);
+-		i = n;
+-	}
+-	return (retval >> (32-i));
+-}
+-
+-#define IT215_SUPPORT
+-void ITUnpack8Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215)
+-//-------------------------------------------------------------------------------------------
+-{
+-	signed char *pDst = pSample;
+-	LPBYTE pSrc = lpMemFile;
+-	DWORD wCount = 0;
+-	DWORD bitbuf = 0;
+-	UINT bitnum = 0;
+-	BYTE bLeft = 0, bTemp = 0, bTemp2 = 0;
+-
+-	while (dwLen)
+-	{
+-		if (!wCount)
+-		{
+-			wCount = 0x8000;
+-			pSrc += 2;
+-			bLeft = 9;
+-			bTemp = bTemp2 = 0;
+-			bitbuf = bitnum = 0;
+-		}
+-		DWORD d = wCount;
+-		if (d > dwLen) d = dwLen;
+-		// Unpacking
+-		DWORD dwPos = 0;
+-		do
+-		{
+-			WORD wBits = (WORD)ITReadBits(bitbuf, bitnum, pSrc, bLeft);
+-			if (bLeft < 7)
+-			{
+-				DWORD i = 1 << (bLeft-1);
+-				DWORD j = wBits & 0xFFFF;
+-				if (i != j) goto UnpackByte;
+-				wBits = (WORD)(ITReadBits(bitbuf, bitnum, pSrc, 3) + 1) & 0xFF;
+-				bLeft = ((BYTE)wBits < bLeft) ? (BYTE)wBits : (BYTE)((wBits+1) & 0xFF);
+-				goto Next;
+-			}
+-			if (bLeft < 9)
+-			{
+-				WORD i = (0xFF >> (9 - bLeft)) + 4;
+-				WORD j = i - 8;
+-				if ((wBits <= j) || (wBits > i)) goto UnpackByte;
+-				wBits -= j;
+-				bLeft = ((BYTE)(wBits & 0xFF) < bLeft) ? (BYTE)(wBits & 0xFF) : (BYTE)((wBits+1) & 0xFF);
+-				goto Next;
+-			}
+-			if (bLeft >= 10) goto SkipByte;
+-			if (wBits >= 256)
+-			{
+-				bLeft = (BYTE)(wBits + 1) & 0xFF;
+-				goto Next;
+-			}
+-		UnpackByte:
+-			if (bLeft < 8)
+-			{
+-				BYTE shift = 8 - bLeft;
+-				signed char c = (signed char)(wBits << shift);
+-				c >>= shift;
+-				wBits = (WORD)c;
+-			}
+-			wBits += bTemp;
+-			bTemp = (BYTE)wBits;
+-			bTemp2 += bTemp;
+-#ifdef IT215_SUPPORT
+-			pDst[dwPos] = (b215) ? bTemp2 : bTemp;
+-#else
+-			pDst[dwPos] = bTemp;
+-#endif
+-		SkipByte:
+-			dwPos++;
+-		Next:
+-			if (pSrc >= lpMemFile+dwMemLength+1) return;
+-		} while (dwPos < d);
+-		// Move On
+-		wCount -= d;
+-		dwLen -= d;
+-		pDst += d;
+-	}
+-}
+-
+-
+-void ITUnpack16Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215)
+-//--------------------------------------------------------------------------------------------
+-{
+-	signed short *pDst = (signed short *)pSample;
+-	LPBYTE pSrc = lpMemFile;
+-	DWORD wCount = 0;
+-	DWORD bitbuf = 0;
+-	UINT bitnum = 0;
+-	BYTE bLeft = 0;
+-	signed short wTemp = 0, wTemp2 = 0;
+-
+-	while (dwLen)
+-	{
+-		if (!wCount)
+-		{
+-			wCount = 0x4000;
+-			pSrc += 2;
+-			bLeft = 17;
+-			wTemp = wTemp2 = 0;
+-			bitbuf = bitnum = 0;
+-		}
+-		DWORD d = wCount;
+-		if (d > dwLen) d = dwLen;
+-		// Unpacking
+-		DWORD dwPos = 0;
+-		do
+-		{
+-			DWORD dwBits = ITReadBits(bitbuf, bitnum, pSrc, bLeft);
+-			if (bLeft < 7)
+-			{
+-				DWORD i = 1 << (bLeft-1);
+-				DWORD j = dwBits;
+-				if (i != j) goto UnpackByte;
+-				dwBits = ITReadBits(bitbuf, bitnum, pSrc, 4) + 1;
+-				bLeft = ((BYTE)(dwBits & 0xFF) < bLeft) ? (BYTE)(dwBits & 0xFF) : (BYTE)((dwBits+1) & 0xFF);
+-				goto Next;
+-			}
+-			if (bLeft < 17)
+-			{
+-				DWORD i = (0xFFFF >> (17 - bLeft)) + 8;
+-				DWORD j = (i - 16) & 0xFFFF;
+-				if ((dwBits <= j) || (dwBits > (i & 0xFFFF))) goto UnpackByte;
+-				dwBits -= j;
+-				bLeft = ((BYTE)(dwBits & 0xFF) < bLeft) ? (BYTE)(dwBits & 0xFF) : (BYTE)((dwBits+1) & 0xFF);
+-				goto Next;
+-			}
+-			if (bLeft >= 18) goto SkipByte;
+-			if (dwBits >= 0x10000)
+-			{
+-				bLeft = (BYTE)(dwBits + 1) & 0xFF;
+-				goto Next;
+-			}
+-		UnpackByte:
+-			if (bLeft < 16)
+-			{
+-				BYTE shift = 16 - bLeft;
+-				signed short c = (signed short)(dwBits << shift);
+-				c >>= shift;
+-				dwBits = (DWORD)c;
+-			}
+-			dwBits += wTemp;
+-			wTemp = (signed short)dwBits;
+-			wTemp2 += wTemp;
+-#ifdef IT215_SUPPORT
+-			pDst[dwPos] = (b215) ? wTemp2 : wTemp;
+-#else
+-			pDst[dwPos] = wTemp;
+-#endif
+-		SkipByte:
+-			dwPos++;
+-		Next:
+-			if (pSrc >= lpMemFile+dwMemLength+1) return;
+-		} while (dwPos < d);
+-		// Move On
+-		wCount -= d;
+-		dwLen -= d;
+-		pDst += d;
+-		if (pSrc >= lpMemFile+dwMemLength) break;
+-	}
+-}
+-
+-UINT CSoundFile::LoadMixPlugins(const void *pData, UINT nLen)
+-//-----------------------------------------------------------
+-{
+-	const BYTE *p = (const BYTE *)pData;
+-	UINT nPos = 0;
+-
+-	while (nPos+8 < nLen)
+-	{
+-		DWORD nPluginSize;
+-		UINT nPlugin;
+-
+-		nPluginSize = bswapLE32(*(DWORD *)(p+nPos+4));
+-		if (nPluginSize > nLen-nPos-8) break;;
+-		if ((bswapLE32(*(DWORD *)(p+nPos))) == 0x58464843)
+-		{
+-			for (UINT ch=0; ch<64; ch++) if (ch*4 < nPluginSize)
+-			{
+-				ChnSettings[ch].nMixPlugin = bswapLE32(*(DWORD *)(p+nPos+8+ch*4));
+-			}
+-		} else
+-		{
+-			if ((p[nPos] != 'F') || (p[nPos+1] != 'X')
+-			 || (p[nPos+2] < '0') || (p[nPos+3] < '0'))
+-			{
+-				break;
+-			}
+-			nPlugin = (p[nPos+2]-'0')*10 + (p[nPos+3]-'0');
+-			if ((nPlugin < MAX_MIXPLUGINS) && (nPluginSize >= sizeof(SNDMIXPLUGININFO)+4))
+-			{
+-				DWORD dwExtra = bswapLE32(*(DWORD *)(p+nPos+8+sizeof(SNDMIXPLUGININFO)));
+-				m_MixPlugins[nPlugin].Info = *(const SNDMIXPLUGININFO *)(p+nPos+8);
+-				m_MixPlugins[nPlugin].Info.dwPluginId1 = bswapLE32(m_MixPlugins[nPlugin].Info.dwPluginId1);
+-				m_MixPlugins[nPlugin].Info.dwPluginId2 = bswapLE32(m_MixPlugins[nPlugin].Info.dwPluginId2);
+-				m_MixPlugins[nPlugin].Info.dwInputRouting = bswapLE32(m_MixPlugins[nPlugin].Info.dwInputRouting);
+-				m_MixPlugins[nPlugin].Info.dwOutputRouting = bswapLE32(m_MixPlugins[nPlugin].Info.dwOutputRouting);
+-				for (UINT j=0; j<4; j++)
+-				{
+-				        m_MixPlugins[nPlugin].Info.dwReserved[j] = bswapLE32(m_MixPlugins[nPlugin].Info.dwReserved[j]);
+-				}
+-				if ((dwExtra) && (dwExtra <= nPluginSize-sizeof(SNDMIXPLUGININFO)-4))
+-				{
+-					m_MixPlugins[nPlugin].nPluginDataSize = 0;
+-					m_MixPlugins[nPlugin].pPluginData = new signed char [dwExtra];
+-					if (m_MixPlugins[nPlugin].pPluginData)
+-					{
+-						m_MixPlugins[nPlugin].nPluginDataSize = dwExtra;
+-						memcpy(m_MixPlugins[nPlugin].pPluginData, p+nPos+8+sizeof(SNDMIXPLUGININFO)+4, dwExtra);
+-					}
+-				}
+-			}
+-		}
+-		nPos += nPluginSize + 8;
+-	}
+-	return nPos;
+-}
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_mdl.cxx audacious-plugins-2.5.4/src/modplug/load_mdl.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_mdl.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_mdl.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,538 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-//////////////////////////////////////////////
+-// DigiTracker (MDL) module loader          //
+-//////////////////////////////////////////////
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#pragma warning(disable:4244)
+-
+-typedef struct MDLSONGHEADER
+-{
+-	DWORD id;	// "DMDL" = 0x4C444D44
+-	BYTE version;
+-} MDLSONGHEADER;
+-
+-
+-typedef struct MDLINFOBLOCK
+-{
+-	CHAR songname[32];
+-	CHAR composer[20];
+-	WORD norders;
+-	WORD repeatpos;
+-	BYTE globalvol;
+-	BYTE speed;
+-	BYTE tempo;
+-	BYTE channelinfo[32];
+-	BYTE seq[256];
+-} MDLINFOBLOCK;
+-
+-
+-typedef struct MDLPATTERNDATA
+-{
+-	BYTE channels;
+-	BYTE lastrow;	// nrows = lastrow+1
+-	CHAR name[16];
+-	WORD data[1];
+-} MDLPATTERNDATA;
+-
+-
+-void ConvertMDLCommand(MODCOMMAND *m, UINT eff, UINT data)
+-//--------------------------------------------------------
+-{
+-	UINT command = 0, param = data;
+-	switch(eff)
+-	{
+-	case 0x01:	command = CMD_PORTAMENTOUP; break;
+-	case 0x02:	command = CMD_PORTAMENTODOWN; break;
+-	case 0x03:	command = CMD_TONEPORTAMENTO; break;
+-	case 0x04:	command = CMD_VIBRATO; break;
+-	case 0x05:	command = CMD_ARPEGGIO; break;
+-	case 0x07:	command = (param < 0x20) ? CMD_SPEED : CMD_TEMPO; break;
+-	case 0x08:	command = CMD_PANNING8; param <<= 1; break;
+-	case 0x0B:	command = CMD_POSITIONJUMP; break;
+-	case 0x0C:	command = CMD_GLOBALVOLUME; break;
+-	case 0x0D:	command = CMD_PATTERNBREAK; param = (data & 0x0F) + (data>>4)*10; break;
+-	case 0x0E:
+-		command = CMD_S3MCMDEX;
+-		switch(data & 0xF0)
+-		{
+-		case 0x00:	command = 0; break; // What is E0x in MDL (there is a bunch) ?
+-		case 0x10:	if (param & 0x0F) { param |= 0xF0; command = CMD_PANNINGSLIDE; } else command = 0; break;
+-		case 0x20:	if (param & 0x0F) { param = (param << 4) | 0x0F; command = CMD_PANNINGSLIDE; } else command = 0; break;
+-		case 0x30:	param = (data & 0x0F) | 0x10; break; // glissando
+-		case 0x40:	param = (data & 0x0F) | 0x30; break; // vibrato waveform
+-		case 0x60:	param = (data & 0x0F) | 0xB0; break;
+-		case 0x70:	param = (data & 0x0F) | 0x40; break; // tremolo waveform
+-		case 0x90:	command = CMD_RETRIG; param &= 0x0F; break;
+-		case 0xA0:	param = (data & 0x0F) << 4; command = CMD_GLOBALVOLSLIDE; break;
+-		case 0xB0:	param = data & 0x0F; command = CMD_GLOBALVOLSLIDE; break;
+-		case 0xF0:	param = ((data >> 8) & 0x0F) | 0xA0; break;
+-		}
+-		break;
+-	case 0x0F:	command = CMD_SPEED; break;
+-                
+-	case 0x10:
+-                if ((param & 0xF0) != 0xE0) {
+-                        command = CMD_VOLUMESLIDE;
+-                        if ((param & 0xF0) == 0xF0) {
+-                                param = ((param << 4) | 0x0F);
+-                        } else {
+-                                param >>= 2;
+-                                if (param > 0xF)
+-                                        param = 0xF;
+-                                param <<= 4;
+-                        }
+-                }
+-                break;
+-	case 0x20:
+-                if ((param & 0xF0) != 0xE0) {
+-                        command = CMD_VOLUMESLIDE;
+-                        if ((param & 0xF0) != 0xF0) {
+-                                param >>= 2;
+-                                if (param > 0xF)
+-                                        param = 0xF;
+-                        }
+-                }
+-                break;
+-                
+-	case 0x30:	command = CMD_RETRIG; break;
+-	case 0x40:	command = CMD_TREMOLO; break;
+-	case 0x50:	command = CMD_TREMOR; break;
+-	case 0xEF:	if (param > 0xFF) param = 0xFF; command = CMD_OFFSET; break;
+-	}
+-	if (command)
+-	{
+-		m->command = command;
+-		m->param = param;
+-	}
+-}
+-
+-
+-void UnpackMDLTrack(MODCOMMAND *pat, UINT nChannels, UINT nRows, UINT nTrack, const BYTE *lpTracks)
+-//-------------------------------------------------------------------------------------------------
+-{
+-	MODCOMMAND cmd, *m = pat;
+-	UINT len = *((WORD *)lpTracks);
+-	UINT pos = 0, row = 0, i;
+-	lpTracks += 2;
+-	for (UINT ntrk=1; ntrk<nTrack; ntrk++)
+-	{
+-		lpTracks += len;
+-		len = *((WORD *)lpTracks);
+-		lpTracks += 2;
+-	}
+-	cmd.note = cmd.instr = 0;
+-	cmd.volcmd = cmd.vol = 0;
+-	cmd.command = cmd.param = 0;
+-	while ((row < nRows) && (pos < len))
+-	{
+-		UINT xx;
+-		BYTE b = lpTracks[pos++];
+-		xx = b >> 2;
+-		switch(b & 0x03)
+-		{
+-		case 0x01:
+-			for (i=0; i<=xx; i++)
+-			{
+-				if (row) *m = *(m-nChannels);
+-				m += nChannels;
+-				row++;
+-				if (row >= nRows) break;
+-			}
+-			break;
+-
+-		case 0x02:
+-			if (xx < row) *m = pat[nChannels*xx];
+-			m += nChannels;
+-			row++;
+-			break;
+-
+-		case 0x03:
+-			{
+-				cmd.note = (xx & 0x01) ? lpTracks[pos++] : 0;
+-				cmd.instr = (xx & 0x02) ? lpTracks[pos++] : 0;
+-				cmd.volcmd = cmd.vol = 0;
+-				cmd.command = cmd.param = 0;
+-				if ((cmd.note < 120-12) && (cmd.note)) cmd.note += 12;
+-				UINT volume = (xx & 0x04) ? lpTracks[pos++] : 0;
+-				UINT commands = (xx & 0x08) ? lpTracks[pos++] : 0;
+-				UINT command1 = commands & 0x0F;
+-				UINT command2 = commands & 0xF0;
+-				UINT param1 = (xx & 0x10) ? lpTracks[pos++] : 0;
+-				UINT param2 = (xx & 0x20) ? lpTracks[pos++] : 0;
+-				if ((command1 == 0x0E) && ((param1 & 0xF0) == 0xF0) && (!command2))
+-				{
+-					param1 = ((param1 & 0x0F) << 8) | param2;
+-					command1 = 0xEF;
+-					command2 = param2 = 0;
+-				}
+-				if (volume)
+-				{
+-					cmd.volcmd = VOLCMD_VOLUME;
+-					cmd.vol = (volume+1) >> 2;
+-				}
+-				ConvertMDLCommand(&cmd, command1, param1);
+-				if ((cmd.command != CMD_SPEED)
+-				 && (cmd.command != CMD_TEMPO)
+-				 && (cmd.command != CMD_PATTERNBREAK))
+-					ConvertMDLCommand(&cmd, command2, param2);
+-				*m = cmd;
+-				m += nChannels;
+-				row++;
+-			}
+-			break;
+-
+-		// Empty Slots
+-		default:
+-			row += xx+1;
+-			m += (xx+1)*nChannels;
+-			if (row >= nRows) break;
+-		}
+-	}
+-}
+-
+-
+-
+-BOOL CSoundFile::ReadMDL(const BYTE *lpStream, DWORD dwMemLength)
+-//---------------------------------------------------------------
+-{
+-	DWORD dwMemPos, dwPos, blocklen, dwTrackPos;
+-	const MDLSONGHEADER *pmsh = (const MDLSONGHEADER *)lpStream;
+-	MDLINFOBLOCK *pmib;
+-	MDLPATTERNDATA *pmpd;
+-	UINT i,j, norders = 0, npatterns = 0, ntracks = 0;
+-	UINT ninstruments = 0, nsamples = 0;
+-	WORD block;
+-	WORD patterntracks[MAX_PATTERNS*32];
+-	BYTE smpinfo[MAX_SAMPLES];
+-	BYTE insvolenv[MAX_INSTRUMENTS];
+-	BYTE inspanenv[MAX_INSTRUMENTS];
+-	LPCBYTE pvolenv, ppanenv, ppitchenv;
+-	UINT nvolenv, npanenv, npitchenv;
+-
+-	if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
+-	if ((bswapLE32(pmsh->id) != 0x4C444D44) || ((pmsh->version & 0xF0) > 0x10)) return FALSE;
+-	memset(patterntracks, 0, sizeof(patterntracks));
+-	memset(smpinfo, 0, sizeof(smpinfo));
+-	memset(insvolenv, 0, sizeof(insvolenv));
+-	memset(inspanenv, 0, sizeof(inspanenv));
+-	dwMemPos = 5;
+-	dwTrackPos = 0;
+-	pvolenv = ppanenv = ppitchenv = NULL;
+-	nvolenv = npanenv = npitchenv = 0;
+-	m_nSamples = m_nInstruments = 0;
+-	m_dwSongFlags |= SONG_INSTRUMENTMODE;
+-	while (dwMemPos+6 < dwMemLength)
+-	{
+-		block = *((WORD *)(lpStream+dwMemPos));
+-		blocklen = *((DWORD *)(lpStream+dwMemPos+2));
+-		block = bswapLE16(block);
+-		blocklen = bswapLE32(blocklen);
+-		dwMemPos += 6;
+-		if (dwMemPos + blocklen > dwMemLength)
+-		{
+-			if (dwMemPos == 11) return FALSE;
+-			break;
+-		}
+-		switch(block)
+-		{
+-		// IN: infoblock
+-		case 0x4E49:
+-			pmib = (MDLINFOBLOCK *)(lpStream+dwMemPos);
+-			memcpy(m_szNames[0], pmib->songname, 32);
+-			norders = bswapLE16(pmib->norders);
+-			if (norders > MAX_ORDERS) norders = MAX_ORDERS;
+-			m_nRestartPos = bswapLE16(pmib->repeatpos);
+-			m_nDefaultGlobalVolume = pmib->globalvol;
+-                        if (m_nDefaultGlobalVolume == 255)
+-                                m_nDefaultGlobalVolume++;
+-			m_nDefaultTempo = pmib->tempo;
+-			m_nDefaultSpeed = pmib->speed;
+-			m_nChannels = 4;
+-			for (i=0; i<32; i++)
+-			{
+-				ChnSettings[i].nVolume = 64;
+-				ChnSettings[i].nPan = (pmib->channelinfo[i] & 0x7F) << 1;
+-				if (pmib->channelinfo[i] & 0x80)
+-					ChnSettings[i].dwFlags |= CHN_MUTE;
+-				else
+-					m_nChannels = i+1;
+-			}
+-			for (j=0; j<norders; j++) Order[j] = pmib->seq[j];
+-			break;
+-		// ME: song message
+-		case 0x454D:
+-			if (blocklen)
+-			{
+-				if (m_lpszSongComments) delete m_lpszSongComments;
+-				m_lpszSongComments = new char[blocklen];
+-				if (m_lpszSongComments)
+-				{
+-					memcpy(m_lpszSongComments, lpStream+dwMemPos, blocklen);
+-					m_lpszSongComments[blocklen-1] = 0;
+-				}
+-			}
+-			break;
+-		// PA: Pattern Data
+-		case 0x4150:
+-			npatterns = lpStream[dwMemPos];
+-			if (npatterns > MAX_PATTERNS) npatterns = MAX_PATTERNS;
+-			dwPos = dwMemPos + 1;
+-			for (i=0; i<npatterns; i++)
+-			{
+-				if (dwPos+18 >= dwMemLength) break;
+-				pmpd = (MDLPATTERNDATA *)(lpStream + dwPos);
+-				if (pmpd->channels > 32) break;
+-				PatternSize[i] = pmpd->lastrow+1;
+-				PatternAllocSize[i] = pmpd->lastrow+1;
+-				if (m_nChannels < pmpd->channels) m_nChannels = pmpd->channels;
+-				dwPos += 18 + 2*pmpd->channels;
+-				for (j=0; j<pmpd->channels; j++)
+-				{
+-					patterntracks[i*32+j] = bswapLE16(pmpd->data[j]);
+-				}
+-			}
+-			break;
+-		// TR: Track Data
+-		case 0x5254:
+-			if (dwTrackPos) break;
+-			ntracks = *((WORD *)(lpStream+dwMemPos));
+-			ntracks = bswapLE16(ntracks);
+-			dwTrackPos = dwMemPos+2;
+-			break;
+-		// II: Instruments
+-		case 0x4949:
+-			ninstruments = lpStream[dwMemPos];
+-			dwPos = dwMemPos+1;
+-			for (i=0; i<ninstruments; i++)
+-			{
+-				UINT nins = lpStream[dwPos];
+-				if ((nins >= MAX_INSTRUMENTS) || (!nins)) break;
+-				if (m_nInstruments < nins) m_nInstruments = nins;
+-				if (!Headers[nins])
+-				{
+-					UINT note = 12;
+-					if ((Headers[nins] = new INSTRUMENTHEADER) == NULL) break;
+-					INSTRUMENTHEADER *penv = Headers[nins];
+-					memset(penv, 0, sizeof(INSTRUMENTHEADER));
+-					memcpy(penv->name, lpStream+dwPos+2, 32);
+-					penv->nGlobalVol = 128;
+-					penv->nPPC = 5*12;
+-					for (j=0; j<lpStream[dwPos+1]; j++)
+-					{
+-						const BYTE *ps = lpStream+dwPos+34+14*j;
+-						while ((note < (UINT)(ps[1]+12)) && (note < 120))
+-						{
+-							penv->NoteMap[note] = note+1;
+-							if (ps[0] < MAX_SAMPLES)
+-							{
+-								int ismp = ps[0];
+-								penv->Keyboard[note] = ps[0];
+-								Ins[ismp].nVolume = ps[2];
+-								Ins[ismp].nPan = ps[4] << 1;
+-								Ins[ismp].nVibType = ps[11];
+-								Ins[ismp].nVibSweep = ps[10];
+-								Ins[ismp].nVibDepth = ps[9];
+-								Ins[ismp].nVibRate = ps[8];
+-							}
+-							penv->nFadeOut = (ps[7] << 8) | ps[6];
+-							if (penv->nFadeOut == 0xFFFF) penv->nFadeOut = 0;
+-							note++;
+-						}
+-						// Use volume envelope ?
+-						if (ps[3] & 0x80)
+-						{
+-							penv->dwFlags |= ENV_VOLUME;
+-							insvolenv[nins] = (ps[3] & 0x3F) + 1;
+-						}
+-						// Use panning envelope ?
+-						if (ps[5] & 0x80)
+-						{
+-							penv->dwFlags |= ENV_PANNING;
+-							inspanenv[nins] = (ps[5] & 0x3F) + 1;
+-						}
+-					}
+-				}
+-				dwPos += 34 + 14*lpStream[dwPos+1];
+-			}
+-			for (j=1; j<=m_nInstruments; j++) if (!Headers[j])
+-			{
+-				Headers[j] = new INSTRUMENTHEADER;
+-				if (Headers[j]) memset(Headers[j], 0, sizeof(INSTRUMENTHEADER));
+-			}
+-			break;
+-		// VE: Volume Envelope
+-		case 0x4556:
+-			if ((nvolenv = lpStream[dwMemPos]) == 0) break;
+-			if (dwMemPos + nvolenv*32 + 1 <= dwMemLength) pvolenv = lpStream + dwMemPos + 1;
+-			break;
+-		// PE: Panning Envelope
+-		case 0x4550:
+-			if ((npanenv = lpStream[dwMemPos]) == 0) break;
+-			if (dwMemPos + npanenv*32 + 1 <= dwMemLength) ppanenv = lpStream + dwMemPos + 1;
+-			break;
+-		// FE: Pitch Envelope
+-		case 0x4546:
+-			if ((npitchenv = lpStream[dwMemPos]) == 0) break;
+-			if (dwMemPos + npitchenv*32 + 1 <= dwMemLength) ppitchenv = lpStream + dwMemPos + 1;
+-			break;
+-		// IS: Sample Infoblock
+-		case 0x5349:
+-			nsamples = lpStream[dwMemPos];
+-			dwPos = dwMemPos+1;
+-			for (i=0; i<nsamples; i++, dwPos += 59)
+-			{
+-				UINT nins = lpStream[dwPos];
+-				if ((nins >= MAX_SAMPLES) || (!nins)) continue;
+-				if (m_nSamples < nins) m_nSamples = nins;
+-				MODINSTRUMENT *pins = &Ins[nins];
+-				memcpy(m_szNames[nins], lpStream+dwPos+1, 32);
+-				memcpy(pins->name, lpStream+dwPos+33, 8);
+-				pins->nC4Speed = *((DWORD *)(lpStream+dwPos+41));
+-				pins->nC4Speed = bswapLE32(pins->nC4Speed);
+-				pins->nLength = *((DWORD *)(lpStream+dwPos+45));
+-				pins->nLength = bswapLE32(pins->nLength);
+-				pins->nLoopStart = *((DWORD *)(lpStream+dwPos+49));
+-				pins->nLoopStart = bswapLE32(pins->nLoopStart);
+-				pins->nLoopEnd = pins->nLoopStart + *((DWORD *)(lpStream+dwPos+53));
+-				pins->nLoopEnd = bswapLE32(pins->nLoopEnd);
+-				if (pins->nLoopEnd > pins->nLoopStart) pins->uFlags |= CHN_LOOP;
+-				pins->nGlobalVol = 64;
+-				if (lpStream[dwPos+58] & 0x01)
+-				{
+-					pins->uFlags |= CHN_16BIT;
+-					pins->nLength >>= 1;
+-					pins->nLoopStart >>= 1;
+-					pins->nLoopEnd >>= 1;
+-				}
+-				if (lpStream[dwPos+58] & 0x02) pins->uFlags |= CHN_PINGPONGLOOP;
+-				smpinfo[nins] = (lpStream[dwPos+58] >> 2) & 3;
+-			}
+-			break;
+-		// SA: Sample Data
+-		case 0x4153:
+-			dwPos = dwMemPos;
+-			for (i=1; i<=m_nSamples; i++) if ((Ins[i].nLength) && (!Ins[i].pSample) && (smpinfo[i] != 3) && (dwPos < dwMemLength))
+-			{
+-				MODINSTRUMENT *pins = &Ins[i];
+-				UINT flags = (pins->uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S;
+-				if (!smpinfo[i])
+-				{
+-					dwPos += ReadSample(pins, flags, (LPSTR)(lpStream+dwPos), dwMemLength - dwPos);
+-				} else
+-				{
+-					DWORD dwLen = *((DWORD *)(lpStream+dwPos));
+-					dwLen = bswapLE32(dwLen);
+-					dwPos += 4;
+-					if ((dwPos+dwLen <= dwMemLength) && (dwLen > 4))
+-					{
+-						flags = (pins->uFlags & CHN_16BIT) ? RS_MDL16 : RS_MDL8;
+-						ReadSample(pins, flags, (LPSTR)(lpStream+dwPos), dwLen);
+-					}
+-					dwPos += dwLen;
+-				}
+-			}
+-			break;
+-		}
+-		dwMemPos += blocklen;
+-	}
+-	// Unpack Patterns
+-	if ((dwTrackPos) && (npatterns) && (m_nChannels) && (ntracks))
+-	{
+-		for (UINT ipat=0; ipat<npatterns; ipat++)
+-		{
+-			if ((Patterns[ipat] = AllocatePattern(PatternSize[ipat], m_nChannels)) == NULL) break;
+-			for (UINT chn=0; chn<m_nChannels; chn++) if ((patterntracks[ipat*32+chn]) && (patterntracks[ipat*32+chn] <= ntracks))
+-			{
+-				MODCOMMAND *m = Patterns[ipat] + chn;
+-				UnpackMDLTrack(m, m_nChannels, PatternSize[ipat], patterntracks[ipat*32+chn], lpStream+dwTrackPos);
+-			}
+-		}
+-	}
+-	// Set up envelopes
+-	for (UINT iIns=1; iIns<=m_nInstruments; iIns++) if (Headers[iIns])
+-	{
+-		INSTRUMENTHEADER *penv = Headers[iIns];
+-		// Setup volume envelope
+-		if ((nvolenv) && (pvolenv) && (insvolenv[iIns]))
+-		{
+-			LPCBYTE pve = pvolenv;
+-			for (UINT nve=0; nve<nvolenv; nve++, pve+=33) if (pve[0]+1 == insvolenv[iIns])
+-			{
+-				WORD vtick = 1;
+-				penv->VolEnv.nNodes = 15;
+-				for (UINT iv=0; iv<15; iv++)
+-				{
+-					if (iv) vtick += pve[iv*2+1];
+-					penv->VolEnv.Ticks[iv] = vtick;
+-					penv->VolEnv.Values[iv] = pve[iv*2+2];
+-					if (!pve[iv*2+1])
+-					{
+-						penv->VolEnv.nNodes = iv+1;
+-						break;
+-					}
+-				}
+-				penv->VolEnv.nSustainStart = penv->VolEnv.nSustainEnd = pve[31] & 0x0F;
+-				if (pve[31] & 0x10) penv->dwFlags |= ENV_VOLSUSTAIN;
+-				if (pve[31] & 0x20) penv->dwFlags |= ENV_VOLLOOP;
+-				penv->VolEnv.nLoopStart = pve[32] & 0x0F;
+-				penv->VolEnv.nLoopEnd = pve[32] >> 4;
+-			}
+-		}
+-		// Setup panning envelope
+-		if ((npanenv) && (ppanenv) && (inspanenv[iIns]))
+-		{
+-			LPCBYTE ppe = ppanenv;
+-			for (UINT npe=0; npe<npanenv; npe++, ppe+=33) if (ppe[0]+1 == inspanenv[iIns])
+-			{
+-				WORD vtick = 1;
+-				penv->PanEnv.nNodes = 15;
+-				for (UINT iv=0; iv<15; iv++)
+-				{
+-					if (iv) vtick += ppe[iv*2+1];
+-					penv->PanEnv.Ticks[iv] = vtick;
+-					penv->PanEnv.Values[iv] = ppe[iv*2+2];
+-					if (!ppe[iv*2+1])
+-					{
+-						penv->PanEnv.nNodes = iv+1;
+-						break;
+-					}
+-				}
+-				if (ppe[31] & 0x10) penv->dwFlags |= ENV_PANSUSTAIN;
+-				if (ppe[31] & 0x20) penv->dwFlags |= ENV_PANLOOP;
+-				penv->PanEnv.nLoopStart = ppe[32] & 0x0F;
+-				penv->PanEnv.nLoopEnd = ppe[32] >> 4;
+-			}
+-		}
+-	}
+-	m_dwSongFlags |= SONG_LINEARSLIDES;
+-	m_nType = MOD_TYPE_MDL;
+-	return TRUE;
+-}
+-
+-
+-/////////////////////////////////////////////////////////////////////////
+-// MDL Sample Unpacking
+-
+-// MDL Huffman ReadBits compression
+-WORD MDLReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n)
+-//-----------------------------------------------------------------
+-{
+-	WORD v = (WORD)(bitbuf & ((1 << n) - 1) );
+-	bitbuf >>= n;
+-	bitnum -= n;
+-	if (bitnum <= 24)
+-	{
+-		bitbuf |= (((DWORD)(*ibuf++)) << bitnum);
+-		bitnum += 8;
+-	}
+-	return v;
+-}
+-
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_med.cxx audacious-plugins-2.5.4/src/modplug/load_med.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_med.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_med.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,919 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>,
+- *          Adam Goode       <adam at evdebs.org> (endian and char fixes for PPC)
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#define MED_LOG
+-
+-#ifdef MED_LOG
+-extern void Log(LPCSTR s, ...);
+-#endif
+-
+-//////////////////////////////////////////////////////////
+-// OctaMed MED file support (import only)
+-
+-// flags
+-#define	MMD_FLAG_FILTERON	0x1
+-#define	MMD_FLAG_JUMPINGON	0x2
+-#define	MMD_FLAG_JUMP8TH	0x4
+-#define	MMD_FLAG_INSTRSATT	0x8 // instruments are attached (this is a module)
+-#define	MMD_FLAG_VOLHEX		0x10
+-#define MMD_FLAG_STSLIDE	0x20 // SoundTracker mode for slides
+-#define MMD_FLAG_8CHANNEL	0x40 // OctaMED 8 channel song
+-#define	MMD_FLAG_SLOWHQ		0x80 // HQ slows playing speed (V2-V4 compatibility)
+-// flags2
+-#define MMD_FLAG2_BMASK		0x1F
+-#define MMD_FLAG2_BPM		0x20
+-#define	MMD_FLAG2_MIX		0x80 // uses Mixing (V7+)
+-// flags3:
+-#define	MMD_FLAG3_STEREO	0x1	// mixing in Stereo mode
+-#define	MMD_FLAG3_FREEPAN	0x2	// free panning
+-#define MMD_FLAG3_GM		0x4 // module designed for GM/XG compatibility
+-
+-
+-// generic MMD tags
+-#define	MMDTAG_END		0
+-#define	MMDTAG_PTR		0x80000000	// data needs relocation
+-#define	MMDTAG_MUSTKNOW	0x40000000	// loader must fail if this isn't recognized
+-#define	MMDTAG_MUSTWARN	0x20000000	// loader must warn if this isn't recognized
+-
+-// ExpData tags
+-// # of effect groups, including the global group (will
+-// override settings in MMDSong struct), default = 1
+-#define	MMDTAG_EXP_NUMFXGROUPS	1
+-#define	MMDTAG_TRK_NAME		(MMDTAG_PTR|1)	// trackinfo tags
+-#define	MMDTAG_TRK_NAMELEN	2				// namelen includes zero term.
+-#define	MMDTAG_TRK_FXGROUP	3
+-// effectinfo tags
+-#define	MMDTAG_FX_ECHOTYPE	1
+-#define MMDTAG_FX_ECHOLEN	2
+-#define	MMDTAG_FX_ECHODEPTH	3
+-#define	MMDTAG_FX_STEREOSEP	4
+-#define	MMDTAG_FX_GROUPNAME	(MMDTAG_PTR|5)	// the Global Effects group shouldn't have name saved!
+-#define	MMDTAG_FX_GRPNAMELEN 6	// namelen includes zero term.
+-
+-#pragma pack(1)
+-
+-typedef struct tagMEDMODULEHEADER
+-{
+-	DWORD id;		// MMD1-MMD3
+-	DWORD modlen;	// Size of file
+-	DWORD song;		// Position in file for this song
+-	WORD psecnum;
+-	WORD pseq;
+-	DWORD blockarr;	// Position in file for blocks
+-	DWORD mmdflags;
+-	DWORD smplarr;	// Position in file for samples
+-	DWORD reserved;
+-	DWORD expdata;	// Absolute offset in file for ExpData (0 if not present)
+-	DWORD reserved2;
+-	WORD pstate;
+-	WORD pblock;
+-	WORD pline;
+-	WORD pseqnum;
+-	WORD actplayline;
+-	BYTE counter;
+-	BYTE extra_songs;	// # of songs - 1
+-} MEDMODULEHEADER;
+-
+-
+-typedef struct tagMMD0SAMPLE
+-{
+-	WORD rep, replen;
+-	BYTE midich;
+-	BYTE midipreset;
+-	BYTE svol;
+-	signed char strans;
+-} MMD0SAMPLE;
+-
+-
+-// Sample header is immediately followed by sample data...
+-typedef struct tagMMDSAMPLEHEADER
+-{
+-	DWORD length;     // length of *one* *unpacked* channel in *bytes*
+-	WORD type;   
+-				// if non-negative
+-					// bits 0-3 reserved for multi-octave instruments, not supported on the PC
+-					// 0x10: 16 bit (otherwise 8 bit)
+-					// 0x20: Stereo (otherwise mono)
+-					// 0x40: Uses DeltaCode
+-					// 0x80: Packed data
+-				// -1: Synth
+-				// -2: Hybrid
+-	// if type indicates packed data, these fields follow, otherwise we go right to the data
+-	WORD packtype;	// Only 1 = ADPCM is supported
+-	WORD subtype;	// Packing subtype
+-		// ADPCM subtype
+-		// 1: g723_40
+-		// 2: g721
+-		// 3: g723_24
+-	BYTE commonflags;	// flags common to all packtypes (none defined so far)
+-	BYTE packerflags;	// flags for the specific packtype
+-	ULONG leftchlen;	// packed length of left channel in bytes
+-	ULONG rightchlen;	// packed length of right channel in bytes (ONLY PRESENT IN STEREO SAMPLES)
+-	BYTE SampleData[1];	// Sample Data
+-} MMDSAMPLEHEADER;
+-
+-
+-// MMD0/MMD1 song header
+-typedef struct tagMMD0SONGHEADER
+-{
+-	MMD0SAMPLE sample[63];
+-	WORD numblocks;		// # of blocks
+-	WORD songlen;		// # of entries used in playseq
+-	BYTE playseq[256];	// Play sequence
+-	WORD deftempo;		// BPM tempo
+-	signed char playtransp;	// Play transpose
+-	BYTE flags;			// 0x10: Hex Volumes | 0x20: ST/NT/PT Slides | 0x40: 8 Channels song
+-	BYTE flags2;		// [b4-b0]+1: Tempo LPB, 0x20: tempo mode, 0x80: mix_conv=on
+-	BYTE tempo2;		// tempo TPL
+-	BYTE trkvol[16];	// track volumes
+-	BYTE mastervol;		// master volume
+-	BYTE numsamples;	// # of samples (max=63)
+-} MMD0SONGHEADER;
+-
+-
+-// MMD2/MMD3 song header
+-typedef struct tagMMD2SONGHEADER
+-{
+-	MMD0SAMPLE sample[63];
+-	WORD numblocks;		// # of blocks
+-	WORD numsections;	// # of sections
+-	DWORD playseqtable;	// filepos of play sequence
+-	DWORD sectiontable;	// filepos of sections table (WORD array)
+-	DWORD trackvols;	// filepos of tracks volume (BYTE array)
+-	WORD numtracks;		// # of tracks (max 64)
+-	WORD numpseqs;		// # of play sequences
+-	DWORD trackpans;	// filepos of tracks pan values (BYTE array)
+-	LONG flags3;		// 0x1:stereo_mix, 0x2:free_panning, 0x4:GM/XG compatibility
+-	WORD voladj;		// vol_adjust (set to 100 if 0)
+-	WORD channels;		// # of channels (4 if =0)
+-	BYTE mix_echotype;	// 1:normal,2:xecho
+-	BYTE mix_echodepth;	// 1..6
+-	WORD mix_echolen;	// > 0
+-	signed char mix_stereosep;	// -4..4
+-	BYTE pad0[223];
+-	WORD deftempo;		// BPM tempo
+-	signed char playtransp;	// play transpose
+-	BYTE flags;			// 0x1:filteron, 0x2:jumpingon, 0x4:jump8th, 0x8:instr_attached, 0x10:hex_vol, 0x20:PT_slides, 0x40:8ch_conv,0x80:hq slows playing speed
+-	BYTE flags2;		// 0x80:mix_conv=on, [b4-b0]+1:tempo LPB, 0x20:tempo_mode
+-	BYTE tempo2;		// tempo TPL
+-	BYTE pad1[16];
+-	BYTE mastervol;		// master volume
+-	BYTE numsamples;	// # of samples (max 63)
+-} MMD2SONGHEADER;
+-
+-// For MMD0 the note information is held in 3 bytes, byte0, byte1, byte2.  For reference we 
+-// number the bits in each byte 0..7, where 0 is the low bit.
+-// The note is held as bits 5..0 of byte0
+-// The instrument is encoded in 6 bits,  bits 7 and 6 of byte0 and bits 7,6,5,4 of byte1
+-// The command number is bits 3,2,1,0 of byte1, command data is in byte2:
+-// For command 0, byte2 represents the second data byte, otherwise byte2
+-// represents the first data byte.
+-typedef struct tagMMD0BLOCK
+-{
+-	BYTE numtracks;
+-	BYTE lines;		// File value is 1 less than actual, so 0 -> 1 line
+-} MMD0BLOCK;		// BYTE data[lines+1][tracks][3];
+-
+-
+-// For MMD1,MMD2,MMD3 the note information is carried in 4 bytes, byte0, byte1,
+-// byte2 and byte3
+-// The note is held as byte0 (values above 0x84 are ignored)
+-// The instrument is held as byte1
+-// The command number is held as byte2, command data is in byte3
+-// For commands 0 and 0x19 byte3 represents the second data byte,
+-// otherwise byte2 represents the first data byte.
+-typedef struct tagMMD1BLOCK
+-{
+-	WORD numtracks;	// Number of tracks, may be > 64, but then that data is skipped.
+-	WORD lines;		// Stored value is 1 less than actual, so 0 -> 1 line
+-	DWORD info;		// Offset of BlockInfo (if 0, no block_info is present)
+-} MMD1BLOCK;
+-
+-
+-typedef struct tagMMD1BLOCKINFO
+-{
+-	DWORD hlmask;		// Unimplemented - ignore
+-	DWORD blockname;	// file offset of block name
+-	DWORD blocknamelen;	// length of block name (including term. 0)
+-	DWORD pagetable;	// file offset of command page table
+-	DWORD cmdexttable;	// file offset of command extension table
+-	DWORD reserved[4];	// future expansion
+-} MMD1BLOCKINFO;
+-
+-
+-// A set of play sequences is stored as an array of ULONG files offsets
+-// Each offset points to the play sequence itself.
+-typedef struct tagMMD2PLAYSEQ
+-{
+-	CHAR name[32];
+-	DWORD command_offs;	// filepos of command table
+-	DWORD reserved;
+-	WORD length;
+-	WORD seq[512];	// skip if > 0x8000
+-} MMD2PLAYSEQ;
+-
+-
+-// A command table contains commands that effect a particular play sequence
+-// entry.  The only commands read in are STOP or POSJUMP, all others are ignored
+-// POSJUMP is presumed to have extra bytes containing a WORD for the position
+-typedef struct tagMMDCOMMAND
+-{
+-	WORD offset;		// Offset within current sequence entry
+-	BYTE cmdnumber;		// STOP (537) or POSJUMP (538) (others skipped)
+-	BYTE extra_count;
+-	BYTE extra_bytes[4];// [extra_count];
+-} MMDCOMMAND;  // Last entry has offset == 0xFFFF, cmd_number == 0 and 0 extrabytes
+-
+-
+-typedef struct tagMMD0EXP
+-{
+-	DWORD nextmod;			// File offset of next Hdr
+-	DWORD exp_smp;			// Pointer to extra instrument data
+-	WORD s_ext_entries;		// Number of extra instrument entries
+-	WORD s_ext_entrsz;		// Size of extra instrument data
+-	DWORD annotxt;
+-	DWORD annolen;
+-	DWORD iinfo;			// Instrument names
+-	WORD i_ext_entries;	
+-	WORD i_ext_entrsz;
+-	DWORD jumpmask;
+-	DWORD rgbtable;
+-	BYTE channelsplit[4];	// Only used if 8ch_conv (extra channel for every nonzero entry)
+-	DWORD n_info;
+-	DWORD songname;			// Song name
+-	DWORD songnamelen;
+-	DWORD dumps;
+-	DWORD mmdinfo;
+-	DWORD mmdrexx;
+-	DWORD mmdcmd3x;
+-	DWORD trackinfo_ofs;	// ptr to song->numtracks ptrs to tag lists
+-	DWORD effectinfo_ofs;	// ptr to group ptrs
+-	DWORD tag_end;
+-} MMD0EXP;
+-
+-#pragma pack()
+-
+-
+-
+-static void MedConvert(MODCOMMAND *p, const MMD0SONGHEADER *pmsh)
+-//---------------------------------------------------------------
+-{
+-	const BYTE bpmvals[9] = { 179,164,152,141,131,123,116,110,104};
+-
+-	UINT command = p->command;
+-	UINT param = p->param;
+-	switch(command)
+-	{
+-	case 0x00:	if (param) command = CMD_ARPEGGIO; else command = 0; break;
+-	case 0x01:	command = CMD_PORTAMENTOUP; break;
+-	case 0x02:	command = CMD_PORTAMENTODOWN; break;
+-	case 0x03:	command = CMD_TONEPORTAMENTO; break;
+-	case 0x04:	command = CMD_VIBRATO; break;
+-	case 0x05:	command = CMD_TONEPORTAVOL; break;
+-	case 0x06:	command = CMD_VIBRATOVOL; break;
+-	case 0x07:	command = CMD_TREMOLO; break;
+-	case 0x0A:	if (param & 0xF0) param &= 0xF0; command = CMD_VOLUMESLIDE; if (!param) command = 0; break;
+-	case 0x0B:	command = CMD_POSITIONJUMP; break;
+-	case 0x0C:	command = CMD_VOLUME;
+-				if (pmsh->flags & MMD_FLAG_VOLHEX)
+-				{
+-					if (param < 0x80)
+-					{
+-						param = (param+1) / 2;
+-					} else command = 0;
+-				} else
+-				{
+-					if (param <= 0x99)
+-					{
+-						param = (param >> 4)*10+((param & 0x0F) % 10);
+-						if (param > 64) param = 64;
+-					} else command = 0;
+-				}
+-				break;
+-	case 0x09:	command = (param < 0x20) ? CMD_SPEED : CMD_TEMPO; break;
+-	case 0x0D:	if (param & 0xF0) param &= 0xF0; command = CMD_VOLUMESLIDE; if (!param) command = 0; break;
+-	case 0x0F:	// Set Tempo / Special
+-		// F.00 = Pattern Break
+-		if (!param)	command = CMD_PATTERNBREAK;	else
+-		// F.01 - F.F0: Set tempo/speed
+-		if (param <= 0xF0)
+-		{
+-			if (pmsh->flags & MMD_FLAG_8CHANNEL)
+-			{
+-				param = (param > 10) ? 99 : bpmvals[param-1];
+-			} else
+-			// F.01 - F.0A: Set Speed
+-			if (param <= 0x0A)
+-			{
+-				command = CMD_SPEED;
+-			} else
+-			// Old tempo
+-			if (!(pmsh->flags2 & MMD_FLAG2_BPM))
+-			{
+-				param = _muldiv(param, 5*715909, 2*474326);
+-			}
+-			// F.0B - F.F0: Set Tempo (assumes LPB=4)
+-			if (param > 0x0A)
+-			{
+-				command = CMD_TEMPO;
+-				if (param < 0x21) param = 0x21;
+-				if (param > 240) param = 240;
+-			}
+-		} else
+-		switch(param)
+-		{
+-		// F.F1: Retrig 2x
+-		case 0xF1:
+-			command = CMD_MODCMDEX;
+-			param = 0x93;
+-			break;
+-		// F.F2: Note Delay 2x
+-		case 0xF2:
+-			command = CMD_MODCMDEX;
+-			param = 0xD3;
+-			break;
+-		// F.F3: Retrig 3x
+-		case 0xF3:
+-			command = CMD_MODCMDEX;
+-			param = 0x92;
+-			break;
+-		// F.F4: Note Delay 1/3
+-		case 0xF4:
+-			command = CMD_MODCMDEX;
+-			param = 0xD2;
+-			break;
+-		// F.F5: Note Delay 2/3
+-		case 0xF5:
+-			command = CMD_MODCMDEX;
+-			param = 0xD4;
+-			break;
+-		// F.F8: Filter Off
+-		case 0xF8:
+-			command = CMD_MODCMDEX;
+-			param = 0x00;
+-			break;
+-		// F.F9: Filter On
+-		case 0xF9:
+-			command = CMD_MODCMDEX;
+-			param = 0x01;
+-			break;
+-		// F.FD: Very fast tone-portamento
+-		case 0xFD:
+-			command = CMD_TONEPORTAMENTO;
+-			param = 0xFF;
+-			break;
+-		// F.FE: End Song
+-		case 0xFE:
+-			command = CMD_SPEED;
+-			param = 0;
+-			break;
+-		// F.FF: Note Cut
+-		case 0xFF:
+-			command = CMD_MODCMDEX;
+-			param = 0xC0;
+-			break;
+-		default:
+-#ifdef MED_LOG
+-			Log("Unknown Fxx command: cmd=0x%02X param=0x%02X\n", command, param);
+-#endif
+-			param = command = 0;
+-		}
+-		break;
+-	// 11.0x: Fine Slide Up
+-	case 0x11:
+-		command = CMD_MODCMDEX;
+-		if (param > 0x0F) param = 0x0F;
+-		param |= 0x10;
+-		break;
+-	// 12.0x: Fine Slide Down
+-	case 0x12:
+-		command = CMD_MODCMDEX;
+-		if (param > 0x0F) param = 0x0F;
+-		param |= 0x20;
+-		break;
+-	// 14.xx: Vibrato
+-	case 0x14:
+-		command = CMD_VIBRATO;
+-		break;
+-	// 15.xx: FineTune
+-	case 0x15:
+-		command = CMD_MODCMDEX;
+-		param &= 0x0F;
+-		param |= 0x50;
+-		break;
+-	// 16.xx: Pattern Loop
+-	case 0x16:
+-		command = CMD_MODCMDEX;
+-		if (param > 0x0F) param = 0x0F;
+-		param |= 0x60;
+-		break;
+-	// 18.xx: Note Cut
+-	case 0x18:
+-		command = CMD_MODCMDEX;
+-		if (param > 0x0F) param = 0x0F;
+-		param |= 0xC0;
+-		break;
+-	// 19.xx: Sample Offset
+-	case 0x19:
+-		command = CMD_OFFSET;
+-		break;
+-	// 1A.0x: Fine Volume Up
+-	case 0x1A:
+-		command = CMD_MODCMDEX;
+-		if (param > 0x0F) param = 0x0F;
+-		param |= 0xA0;
+-		break;
+-	// 1B.0x: Fine Volume Down
+-	case 0x1B:
+-		command = CMD_MODCMDEX;
+-		if (param > 0x0F) param = 0x0F;
+-		param |= 0xB0;
+-		break;
+-	// 1D.xx: Pattern Break
+-	case 0x1D:
+-		command = CMD_PATTERNBREAK;
+-		break;
+-	// 1E.0x: Pattern Delay
+-	case 0x1E:
+-		command = CMD_MODCMDEX;
+-		if (param > 0x0F) param = 0x0F;
+-		param |= 0xE0;
+-		break;
+-	// 1F.xy: Retrig
+-	case 0x1F:
+-		command = CMD_RETRIG;
+-		param &= 0x0F;
+-		break;
+-	// 2E.xx: set panning
+-	case 0x2E:
+-		command = CMD_MODCMDEX;
+-		param = ((param + 0x10) & 0xFF) >> 1;
+-		if (param > 0x0F) param = 0x0F;
+-		param |= 0x80;
+-		break;
+-	default:
+-#ifdef MED_LOG
+-		// 0x2E ?
+-		Log("Unknown command: cmd=0x%02X param=0x%02X\n", command, param);
+-#endif
+-		command = param = 0;
+-	}
+-	p->command = command;
+-	p->param = param;
+-}
+-
+-
+-BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength)
+-//---------------------------------------------------------------
+-{
+-	const MEDMODULEHEADER *pmmh;
+-	const MMD0SONGHEADER *pmsh;
+-	const MMD2SONGHEADER *pmsh2;
+-	const MMD0EXP *pmex;
+-	DWORD dwBlockArr, dwSmplArr, dwExpData, wNumBlocks;
+-	LPDWORD pdwTable;
+-	CHAR version;
+-	UINT deftempo;
+-	int playtransp = 0;
+-
+-	if ((!lpStream) || (dwMemLength < 0x200)) return FALSE;
+-	pmmh = (MEDMODULEHEADER *)lpStream;
+-	if (((pmmh->id & 0x00FFFFFF) != 0x444D4D) || (!pmmh->song)) return FALSE;
+-	// Check for 'MMDx'
+-	DWORD dwSong = bswapBE32(pmmh->song);
+-	if ((dwSong >= dwMemLength) || (dwSong + sizeof(MMD0SONGHEADER) >= dwMemLength)) return FALSE;
+-	version = (signed char)((pmmh->id >> 24) & 0xFF);
+-	if ((version < '0') || (version > '3')) return FALSE;
+-#ifdef MED_LOG
+-	Log("\nLoading MMD%c module (flags=0x%02X)...\n", version, bswapBE32(pmmh->mmdflags));
+-	Log("  modlen   = %d\n", bswapBE32(pmmh->modlen));
+-	Log("  song     = 0x%08X\n", bswapBE32(pmmh->song));
+-	Log("  psecnum  = %d\n", bswapBE16(pmmh->psecnum));
+-	Log("  pseq     = %d\n", bswapBE16(pmmh->pseq));
+-	Log("  blockarr = 0x%08X\n", bswapBE32(pmmh->blockarr));
+-	Log("  mmdflags = 0x%08X\n", bswapBE32(pmmh->mmdflags));
+-	Log("  smplarr  = 0x%08X\n", bswapBE32(pmmh->smplarr));
+-	Log("  reserved = 0x%08X\n", bswapBE32(pmmh->reserved));
+-	Log("  expdata  = 0x%08X\n", bswapBE32(pmmh->expdata));
+-	Log("  reserved2= 0x%08X\n", bswapBE32(pmmh->reserved2));
+-	Log("  pstate   = %d\n", bswapBE16(pmmh->pstate));
+-	Log("  pblock   = %d\n", bswapBE16(pmmh->pblock));
+-	Log("  pline    = %d\n", bswapBE16(pmmh->pline));
+-	Log("  pseqnum  = %d\n", bswapBE16(pmmh->pseqnum));
+-	Log("  actplayline=%d\n", bswapBE16(pmmh->actplayline));
+-	Log("  counter  = %d\n", pmmh->counter);
+-	Log("  extra_songs = %d\n", pmmh->extra_songs);
+-	Log("\n");
+-#endif
+-	m_nType = MOD_TYPE_MED;
+-	m_nSongPreAmp = 0x20;
+-	dwBlockArr = bswapBE32(pmmh->blockarr);
+-	dwSmplArr = bswapBE32(pmmh->smplarr);
+-	dwExpData = bswapBE32(pmmh->expdata);
+-	if ((dwExpData) && (dwExpData+sizeof(MMD0EXP) < dwMemLength))
+-		pmex = (MMD0EXP *)(lpStream+dwExpData);
+-	else
+-		pmex = NULL;
+-	pmsh = (MMD0SONGHEADER *)(lpStream + dwSong);
+-	pmsh2 = (MMD2SONGHEADER *)pmsh;
+-#ifdef MED_LOG
+-	if (version < '2')
+-	{
+-		Log("MMD0 Header:\n");
+-		Log("  numblocks  = %d\n", bswapBE16(pmsh->numblocks));
+-		Log("  songlen    = %d\n", bswapBE16(pmsh->songlen));
+-		Log("  playseq    = ");
+-		for (UINT idbg1=0; idbg1<16; idbg1++) Log("%2d, ", pmsh->playseq[idbg1]);
+-		Log("...\n");
+-		Log("  deftempo   = 0x%04X\n", bswapBE16(pmsh->deftempo));
+-		Log("  playtransp = %d\n", (signed char)pmsh->playtransp);
+-		Log("  flags(1,2) = 0x%02X, 0x%02X\n", pmsh->flags, pmsh->flags2);
+-		Log("  tempo2     = %d\n", pmsh->tempo2);
+-		Log("  trkvol     = ");
+-		for (UINT idbg2=0; idbg2<16; idbg2++) Log("0x%02X, ", pmsh->trkvol[idbg2]);
+-		Log("...\n");
+-		Log("  mastervol  = 0x%02X\n", pmsh->mastervol);
+-		Log("  numsamples = %d\n", pmsh->numsamples);
+-	} else
+-	{
+-		Log("MMD2 Header:\n");
+-		Log("  numblocks  = %d\n", bswapBE16(pmsh2->numblocks));
+-		Log("  numsections= %d\n", bswapBE16(pmsh2->numsections));
+-		Log("  playseqptr = 0x%04X\n", bswapBE32(pmsh2->playseqtable));
+-		Log("  sectionptr = 0x%04X\n", bswapBE32(pmsh2->sectiontable));
+-		Log("  trackvols  = 0x%04X\n", bswapBE32(pmsh2->trackvols));
+-		Log("  numtracks  = %d\n", bswapBE16(pmsh2->numtracks));
+-		Log("  numpseqs   = %d\n", bswapBE16(pmsh2->numpseqs));
+-		Log("  trackpans  = 0x%04X\n", bswapBE32(pmsh2->trackpans));
+-		Log("  flags3     = 0x%08X\n", bswapBE32(pmsh2->flags3));
+-		Log("  voladj     = %d\n", bswapBE16(pmsh2->voladj));
+-		Log("  channels   = %d\n", bswapBE16(pmsh2->channels));
+-		Log("  echotype   = %d\n", pmsh2->mix_echotype);
+-		Log("  echodepth  = %d\n", pmsh2->mix_echodepth);
+-		Log("  echolen    = %d\n", bswapBE16(pmsh2->mix_echolen));
+-		Log("  stereosep  = %d\n", (signed char)pmsh2->mix_stereosep);
+-		Log("  deftempo   = 0x%04X\n", bswapBE16(pmsh2->deftempo));
+-		Log("  playtransp = %d\n", (signed char)pmsh2->playtransp);
+-		Log("  flags(1,2) = 0x%02X, 0x%02X\n", pmsh2->flags, pmsh2->flags2);
+-		Log("  tempo2     = %d\n", pmsh2->tempo2);
+-		Log("  mastervol  = 0x%02X\n", pmsh2->mastervol);
+-		Log("  numsamples = %d\n", pmsh->numsamples);
+-	}
+-	Log("\n");
+-#endif
+-	wNumBlocks = bswapBE16(pmsh->numblocks);
+-	m_nChannels = 4;
+-	m_nSamples = pmsh->numsamples;
+-	if (m_nSamples > 63) m_nSamples = 63;
+-	m_nStereoSeparation = ((pmsh2->mix_stereosep < 0) ? -32 : 32) * pmsh2->mix_stereosep;
+-	// Tempo
+-	m_nDefaultTempo = 125;
+-	deftempo = bswapBE16(pmsh->deftempo);
+-	if (!deftempo) deftempo = 125;
+-	if (pmsh->flags2 & MMD_FLAG2_BPM)
+-	{
+-		UINT tempo_tpl = (pmsh->flags2 & MMD_FLAG2_BMASK) + 1;
+-		if (!tempo_tpl) tempo_tpl = 4;
+-		deftempo *= tempo_tpl;
+-		deftempo /= 4;
+-	#ifdef MED_LOG
+-		Log("newtempo: %3d bpm (bpm=%3d lpb=%2d)\n", deftempo, bswapBE16(pmsh->deftempo), (pmsh->flags2 & MMD_FLAG2_BMASK)+1);
+-	#endif
+-	} else
+-	{
+-		deftempo = _muldiv(deftempo, 5*715909, 2*474326);
+-	#ifdef MED_LOG
+-		Log("oldtempo: %3d bpm (bpm=%3d)\n", deftempo, bswapBE16(pmsh->deftempo));
+-	#endif
+-	}
+-	// Speed
+-	m_nDefaultSpeed = pmsh->tempo2;
+-	if (!m_nDefaultSpeed) m_nDefaultSpeed = 6;
+-	if (deftempo < 0x21) deftempo = 0x21;
+-	if (deftempo > 255)
+-	{
+-		while ((m_nDefaultSpeed > 3) && (deftempo > 260))
+-		{
+-			deftempo = (deftempo * (m_nDefaultSpeed - 1)) / m_nDefaultSpeed;
+-			m_nDefaultSpeed--;
+-		}
+-		if (deftempo > 255) deftempo = 255;
+-	}
+-	m_nDefaultTempo = deftempo;
+-	// Reading Samples
+-	for (UINT iSHdr=0; iSHdr<m_nSamples; iSHdr++)
+-	{
+-		MODINSTRUMENT *pins = &Ins[iSHdr+1];
+-		pins->nLoopStart = bswapBE16(pmsh->sample[iSHdr].rep) << 1;
+-		pins->nLoopEnd = pins->nLoopStart + (bswapBE16(pmsh->sample[iSHdr].replen) << 1);
+-		pins->nVolume = (pmsh->sample[iSHdr].svol << 2);
+-		pins->nGlobalVol = 64;
+-		if (pins->nVolume > 256) pins->nVolume = 256;
+-		pins->RelativeTone = -12 * pmsh->sample[iSHdr].strans;
+-		pins->nPan = 128;
+-		if (pins->nLoopEnd) pins->uFlags |= CHN_LOOP;
+-	}
+-	// Common Flags
+-	if (!(pmsh->flags & 0x20)) m_dwSongFlags |= SONG_FASTVOLSLIDES;
+-	// Reading play sequence
+-	if (version < '2')
+-	{
+-		UINT nbo = pmsh->songlen >> 8;
+-		if (nbo >= MAX_ORDERS) nbo = MAX_ORDERS-1;
+-		if (!nbo) nbo = 1;
+-		memcpy(Order, pmsh->playseq, nbo);
+-		playtransp = pmsh->playtransp;
+-	} else
+-	{
+-		UINT nOrders, nSections;
+-		UINT nTrks = bswapBE16(pmsh2->numtracks);
+-		if ((nTrks >= 4) && (nTrks <= 32)) m_nChannels = nTrks;
+-		DWORD playseqtable = bswapBE32(pmsh2->playseqtable);
+-		UINT numplayseqs = bswapBE16(pmsh2->numpseqs);
+-		if (!numplayseqs) numplayseqs = 1;
+-		nOrders = 0;
+-		nSections = bswapBE16(pmsh2->numsections);
+-		DWORD sectiontable = bswapBE32(pmsh2->sectiontable);
+-		if ((!nSections) || (!sectiontable) || (sectiontable >= dwMemLength-2)) nSections = 1;
+-		nOrders = 0;
+-		for (UINT iSection=0; iSection<nSections; iSection++)
+-		{
+-			UINT nplayseq = 0;
+-			if ((sectiontable) && (sectiontable < dwMemLength-2))
+-			{
+-				nplayseq = lpStream[sectiontable+1];
+-				sectiontable += 2; // WORDs
+-			} else
+-			{
+-				nSections = 0;
+-			}
+-			UINT pseq = 0;
+-			
+-			if ((playseqtable) && (playseqtable + nplayseq*4 < dwMemLength))
+-			{
+-				pseq = bswapBE32(((LPDWORD)(lpStream+playseqtable))[nplayseq]);
+-			}
+-			if ((pseq) && (pseq < dwMemLength - sizeof(MMD2PLAYSEQ)))
+-			{
+-				MMD2PLAYSEQ *pmps = (MMD2PLAYSEQ *)(lpStream + pseq);
+-				if (!m_szNames[0][0]) memcpy(m_szNames[0], pmps->name, 31);
+-				UINT n = bswapBE16(pmps->length);
+-				if (pseq+n <= dwMemLength)
+-				{
+-					for (UINT i=0; i<n; i++)
+-					{
+-						UINT seqval = pmps->seq[i] >> 8;
+-						if ((seqval < wNumBlocks) && (nOrders < MAX_ORDERS-1))
+-						{
+-							Order[nOrders++] = seqval;
+-						}
+-					}
+-				}
+-			}
+-		}
+-		playtransp = pmsh2->playtransp;
+-		while (nOrders < MAX_ORDERS) Order[nOrders++] = 0xFF;
+-	}
+-	// Reading Expansion structure
+-	if (pmex)
+-	{
+-		// Channel Split
+-		if ((m_nChannels == 4) && (pmsh->flags & 0x40))
+-		{
+-			for (UINT i8ch=0; i8ch<4; i8ch++)
+-			{
+-				if (pmex->channelsplit[i8ch]) m_nChannels++;
+-			}
+-		}
+-		// Song Comments
+-		UINT annotxt = bswapBE32(pmex->annotxt);
+-		UINT annolen = bswapBE32(pmex->annolen);
+-		if ((annotxt) && (annolen) && (annotxt+annolen <= dwMemLength))
+-		{
+-			m_lpszSongComments = new char[annolen+1];
+-			memcpy(m_lpszSongComments, lpStream+annotxt, annolen);
+-			m_lpszSongComments[annolen] = 0;
+-		}
+-		// Song Name
+-		UINT songname = bswapBE32(pmex->songname);
+-		UINT songnamelen = bswapBE32(pmex->songnamelen);
+-		if ((songname) && (songnamelen) && (songname+songnamelen <= dwMemLength))
+-		{
+-			if (songnamelen > 31) songnamelen = 31;
+-			memcpy(m_szNames[0], lpStream+songname, songnamelen);
+-		}
+-		// Sample Names
+-		DWORD smpinfoex = bswapBE32(pmex->iinfo);
+-		if (smpinfoex)
+-		{
+-			DWORD iinfoptr = bswapBE32(pmex->iinfo);
+-			UINT ientries = bswapBE16(pmex->i_ext_entries);
+-			UINT ientrysz = bswapBE16(pmex->i_ext_entrsz);
+-
+-			if ((iinfoptr) && (ientrysz < 256) && (iinfoptr + ientries*ientrysz < dwMemLength))
+-			{
+-				LPCSTR psznames = (LPCSTR)(lpStream + iinfoptr);
+-				UINT maxnamelen = ientrysz;
+-				if (maxnamelen > 32) maxnamelen = 32;
+-				for (UINT i=0; i<ientries; i++) if (i < m_nSamples)
+-				{
+-					lstrcpyn(m_szNames[i+1], psznames + i*ientrysz, maxnamelen);
+-				}
+-			}
+-		}
+-		// Track Names
+-		DWORD trackinfo_ofs = bswapBE32(pmex->trackinfo_ofs);
+-		if ((trackinfo_ofs) && (trackinfo_ofs + m_nChannels * 4 < dwMemLength))
+-		{
+-			DWORD *ptrktags = (DWORD *)(lpStream + trackinfo_ofs);
+-			for (UINT i=0; i<m_nChannels; i++)
+-			{
+-				DWORD trknameofs = 0, trknamelen = 0;
+-				DWORD trktagofs = bswapBE32(ptrktags[i]);
+-				if (trktagofs)
+-				{
+-					while (trktagofs+8 < dwMemLength)
+-					{
+-						DWORD ntag = bswapBE32(*(DWORD *)(lpStream + trktagofs));
+-						if (ntag == MMDTAG_END) break;
+-						DWORD tagdata = bswapBE32(*(DWORD *)(lpStream + trktagofs + 4));
+-						switch(ntag)
+-						{
+-						case MMDTAG_TRK_NAMELEN:	trknamelen = tagdata; break;
+-						case MMDTAG_TRK_NAME:		trknameofs = tagdata; break;
+-						}
+-						trktagofs += 8;
+-					}
+-					if (trknamelen > MAX_CHANNELNAME) trknamelen = MAX_CHANNELNAME;
+-					if ((trknameofs) && (trknameofs + trknamelen < dwMemLength))
+-					{
+-						lstrcpyn(ChnSettings[i].szName, (LPCSTR)(lpStream+trknameofs), MAX_CHANNELNAME);
+-					}
+-				}
+-			}
+-		}
+-	}
+-	// Reading samples
+-	if (dwSmplArr > dwMemLength - 4*m_nSamples) return TRUE;
+-	pdwTable = (LPDWORD)(lpStream + dwSmplArr);
+-	for (UINT iSmp=0; iSmp<m_nSamples; iSmp++) if (pdwTable[iSmp])
+-	{
+-		UINT dwPos = bswapBE32(pdwTable[iSmp]);
+-		if ((dwPos >= dwMemLength) || (dwPos + sizeof(MMDSAMPLEHEADER) >= dwMemLength)) continue;
+-		MMDSAMPLEHEADER *psdh = (MMDSAMPLEHEADER *)(lpStream + dwPos);
+-		UINT len = bswapBE32(psdh->length);
+-	#ifdef MED_LOG
+-		Log("SampleData %d: stype=0x%02X len=%d\n", iSmp, bswapBE16(psdh->type), len);
+-	#endif
+-		if ((len > MAX_SAMPLE_LENGTH) || (dwPos + len + 6 > dwMemLength)) len = 0;
+-		UINT flags = RS_PCM8S, stype = bswapBE16(psdh->type);
+-		LPSTR psdata = (LPSTR)(lpStream + dwPos + 6);
+-		if (stype & 0x80)
+-		{
+-			psdata += (stype & 0x20) ? 14 : 6;
+-		} else
+-		{
+-			if (stype & 0x10)
+-			{
+-				Ins[iSmp+1].uFlags |= CHN_16BIT;
+-				len /= 2;
+-				flags = (stype & 0x20) ? RS_STPCM16M : RS_PCM16M;
+-			} else
+-			{
+-				flags = (stype & 0x20) ? RS_STPCM8S : RS_PCM8S;
+-			}
+-			if (stype & 0x20) len /= 2;
+-		}
+-		Ins[iSmp+1].nLength = len;
+-		ReadSample(&Ins[iSmp+1], flags, psdata, dwMemLength - dwPos - 6);
+-	}
+-	// Reading patterns (blocks)
+-	if (wNumBlocks > MAX_PATTERNS) wNumBlocks = MAX_PATTERNS;
+-	if ((!dwBlockArr) || (dwBlockArr > dwMemLength - 4*wNumBlocks)) return TRUE;
+-	pdwTable = (LPDWORD)(lpStream + dwBlockArr);
+-	playtransp += (version == '3') ? 24 : 48;
+-	for (UINT iBlk=0; iBlk<wNumBlocks; iBlk++)
+-	{
+-		UINT dwPos = bswapBE32(pdwTable[iBlk]);
+-		if ((!dwPos) || (dwPos >= dwMemLength) || (dwPos >= dwMemLength - 8)) continue;
+-		UINT lines = 64, tracks = 4;
+-		if (version == '0')
+-		{
+-			const MMD0BLOCK *pmb = (const MMD0BLOCK *)(lpStream + dwPos);
+-			lines = pmb->lines + 1;
+-			tracks = pmb->numtracks;
+-			if (!tracks) tracks = m_nChannels;
+-			if ((Patterns[iBlk] = AllocatePattern(lines, m_nChannels)) == NULL) continue;
+-			PatternSize[iBlk] = lines;
+-			PatternAllocSize[iBlk] = lines;
+-			MODCOMMAND *p = Patterns[iBlk];
+-			LPBYTE s = (LPBYTE)(lpStream + dwPos + 2);
+-			UINT maxlen = tracks*lines*3;
+-			if (maxlen + dwPos > dwMemLength - 2) break;
+-			for (UINT y=0; y<lines; y++)
+-			{
+-				for (UINT x=0; x<tracks; x++, s+=3) if (x < m_nChannels)
+-				{
+-					BYTE note = s[0] & 0x3F;
+-					BYTE instr = s[1] >> 4;
+-					if (s[0] & 0x80) instr |= 0x10;
+-					if (s[0] & 0x40) instr |= 0x20;
+-					if ((note) && (note <= 132)) p->note = note + playtransp;
+-					p->instr = instr;
+-					p->command = s[1] & 0x0F;
+-					p->param = s[2];
+-					// if (!iBlk) Log("%02X.%02X.%02X | ", s[0], s[1], s[2]);
+-					MedConvert(p, pmsh);
+-					p++;
+-				}
+-				//if (!iBlk) Log("\n");
+-			}
+-		} else
+-		{
+-			MMD1BLOCK *pmb = (MMD1BLOCK *)(lpStream + dwPos);
+-		#ifdef MED_LOG
+-			Log("MMD1BLOCK:   lines=%2d, tracks=%2d, offset=0x%04X\n",
+-				bswapBE16(pmb->lines), bswapBE16(pmb->numtracks), bswapBE32(pmb->info));
+-		#endif
+-			MMD1BLOCKINFO *pbi = NULL;
+-			BYTE *pcmdext = NULL;
+-			lines = (pmb->lines >> 8) + 1;
+-			tracks = pmb->numtracks >> 8;
+-			if (!tracks) tracks = m_nChannels;
+-			if ((Patterns[iBlk] = AllocatePattern(lines, m_nChannels)) == NULL) continue;
+-			PatternSize[iBlk] = (WORD)lines;
+-			PatternAllocSize[iBlk] = (WORD)lines;
+-			DWORD dwBlockInfo = bswapBE32(pmb->info);
+-			if ((dwBlockInfo) && (dwBlockInfo < dwMemLength - sizeof(MMD1BLOCKINFO)))
+-			{
+-				pbi = (MMD1BLOCKINFO *)(lpStream + dwBlockInfo);
+-			#ifdef MED_LOG
+-				Log("  BLOCKINFO: blockname=0x%04X namelen=%d pagetable=0x%04X &cmdexttable=0x%04X\n",
+-					bswapBE32(pbi->blockname), bswapBE32(pbi->blocknamelen), bswapBE32(pbi->pagetable), bswapBE32(pbi->cmdexttable));
+-			#endif
+-				if ((pbi->blockname) && (pbi->blocknamelen))
+-				{
+-					DWORD nameofs = bswapBE32(pbi->blockname);
+-					UINT namelen = bswapBE32(pbi->blocknamelen);
+-					if ((nameofs < dwMemLength) && (nameofs+namelen < dwMemLength))
+-					{
+-						SetPatternName(iBlk, (LPCSTR)(lpStream+nameofs));
+-					}
+-				}
+-				if (pbi->cmdexttable)
+-				{
+-					DWORD cmdexttable = bswapBE32(pbi->cmdexttable);
+-					if (cmdexttable < dwMemLength - 4)
+-					{
+-						cmdexttable = bswapBE32(*(DWORD *)(lpStream + cmdexttable));
+-						if ((cmdexttable) && (cmdexttable <= dwMemLength - lines*tracks))
+-						{
+-							pcmdext = (BYTE *)(lpStream + cmdexttable);
+-						}
+-					}
+-				}
+-			}
+-			MODCOMMAND *p = Patterns[iBlk];
+-			LPBYTE s = (LPBYTE)(lpStream + dwPos + 8);
+-			UINT maxlen = tracks*lines*4;
+-			if (maxlen + dwPos > dwMemLength - 8) break;
+-			for (UINT y=0; y<lines; y++)
+-			{
+-				for (UINT x=0; x<tracks; x++, s+=4) if (x < m_nChannels)
+-				{
+-					BYTE note = s[0];
+-					if ((note) && (note <= 132))
+-					{
+-						int rnote = note + playtransp;
+-						if (rnote < 1) rnote = 1;
+-						if (rnote > 120) rnote = 120;
+-						p->note = (BYTE)rnote;
+-					}
+-					p->instr = s[1];
+-					p->command = s[2];
+-					p->param = s[3];
+-					if (pcmdext) p->vol = pcmdext[x];
+-					MedConvert(p, pmsh);
+-					p++;
+-				}
+-				if (pcmdext) pcmdext += tracks;
+-			}
+-		}
+-	}
+-	// Setup channel pan positions
+-	for (UINT iCh=0; iCh<m_nChannels; iCh++)
+-	{
+-		ChnSettings[iCh].nPan = (((iCh&3) == 1) || ((iCh&3) == 2)) ? 0xC0 : 0x40;
+-		ChnSettings[iCh].nVolume = 64;
+-	}
+-	return TRUE;
+-}
+-
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_mod.cxx audacious-plugins-2.5.4/src/modplug/load_mod.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_mod.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_mod.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,358 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>,
+- *          Adam Goode       <adam at evdebs.org> (endian and char fixes for PPC)
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#pragma warning(disable:4244)
+-
+-extern WORD ProTrackerPeriodTable[6*12];
+-
+-//////////////////////////////////////////////////////////
+-// ProTracker / NoiseTracker MOD/NST file support
+-
+-void CSoundFile::ConvertModCommand(MODCOMMAND *m) const
+-//-----------------------------------------------------
+-{
+-	UINT command = m->command, param = m->param;
+-
+-	switch(command)
+-	{
+-	case 0x00:	if (param) command = CMD_ARPEGGIO; break;
+-	case 0x01:	command = CMD_PORTAMENTOUP; break;
+-	case 0x02:	command = CMD_PORTAMENTODOWN; break;
+-	case 0x03:	command = CMD_TONEPORTAMENTO; break;
+-	case 0x04:	command = CMD_VIBRATO; break;
+-	case 0x05:	command = CMD_TONEPORTAVOL; if (param & 0xF0) param &= 0xF0; break;
+-	case 0x06:	command = CMD_VIBRATOVOL; if (param & 0xF0) param &= 0xF0; break;
+-	case 0x07:	command = CMD_TREMOLO; break;
+-	case 0x08:	command = CMD_PANNING8; break;
+-	case 0x09:	command = CMD_OFFSET; break;
+-	case 0x0A:	command = CMD_VOLUMESLIDE; if (param & 0xF0) param &= 0xF0; break;
+-	case 0x0B:	command = CMD_POSITIONJUMP; break;
+-	case 0x0C:	command = CMD_VOLUME; break;
+-	case 0x0D:	command = CMD_PATTERNBREAK; param = ((param >> 4) * 10) + (param & 0x0F); break;
+-	case 0x0E:	command = CMD_MODCMDEX; break;
+-	case 0x0F:	command = (param <= (UINT)((m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) ? 0x1F : 0x20)) ? CMD_SPEED : CMD_TEMPO;
+-				if ((param == 0xFF) && (m_nSamples == 15)) command = 0; break;
+-	// Extension for XM extended effects
+-	case 'G' - 55:	command = CMD_GLOBALVOLUME; break;
+-	case 'H' - 55:	command = CMD_GLOBALVOLSLIDE; if (param & 0xF0) param &= 0xF0; break;
+-	case 'K' - 55:	command = CMD_KEYOFF; break;
+-	case 'L' - 55:	command = CMD_SETENVPOSITION; break;
+-	case 'M' - 55:	command = CMD_CHANNELVOLUME; break;
+-	case 'N' - 55:	command = CMD_CHANNELVOLSLIDE; break;
+-	case 'P' - 55:	command = CMD_PANNINGSLIDE; if (param & 0xF0) param &= 0xF0; break;
+-	case 'R' - 55:	command = CMD_RETRIG; break;
+-	case 'T' - 55:	command = CMD_TREMOR; break;
+-	case 'X' - 55:	command = CMD_XFINEPORTAUPDOWN;	break;
+-	case 'Y' - 55:	command = CMD_PANBRELLO; break;
+-	case 'Z' - 55:	command = CMD_MIDI;	break;
+-	default:	command = 0;
+-	}
+-	m->command = command;
+-	m->param = param;
+-}
+-
+-
+-WORD CSoundFile::ModSaveCommand(const MODCOMMAND *m, BOOL bXM) const
+-//------------------------------------------------------------------
+-{
+-	UINT command = m->command & 0x3F, param = m->param;
+-
+-	switch(command)
+-	{
+-	case 0:						command = param = 0; break;
+-	case CMD_ARPEGGIO:			command = 0; break;
+-	case CMD_PORTAMENTOUP:
+-		if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_STM))
+-		{
+-			if ((param & 0xF0) == 0xE0) { command=0x0E; param=((param & 0x0F) >> 2)|0x10; break; }
+-			else if ((param & 0xF0) == 0xF0) { command=0x0E; param &= 0x0F; param|=0x10; break; }
+-		}
+-		command = 0x01;
+-		break;
+-	case CMD_PORTAMENTODOWN:
+-		if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_STM))
+-		{
+-			if ((param & 0xF0) == 0xE0) { command=0x0E; param=((param & 0x0F) >> 2)|0x20; break; }
+-			else if ((param & 0xF0) == 0xF0) { command=0x0E; param &= 0x0F; param|=0x20; break; }
+-		}
+-		command = 0x02;
+-		break;
+-	case CMD_TONEPORTAMENTO:	command = 0x03; break;
+-	case CMD_VIBRATO:			command = 0x04; break;
+-	case CMD_TONEPORTAVOL:		command = 0x05; break;
+-	case CMD_VIBRATOVOL:		command = 0x06; break;
+-	case CMD_TREMOLO:			command = 0x07; break;
+-	case CMD_PANNING8:			
+-		command = 0x08;
+-		if (bXM)
+-		{
+-			if ((m_nType != MOD_TYPE_IT) && (m_nType != MOD_TYPE_XM) && (param <= 0x80))
+-			{
+-				param <<= 1;
+-				if (param > 255) param = 255;
+-			}
+-		} else
+-		{
+-			if ((m_nType == MOD_TYPE_IT) || (m_nType == MOD_TYPE_XM)) param >>= 1;
+-		}
+-		break;
+-	case CMD_OFFSET:			command = 0x09; break;
+-	case CMD_VOLUMESLIDE:		command = 0x0A; break;
+-	case CMD_POSITIONJUMP:		command = 0x0B; break;
+-	case CMD_VOLUME:			command = 0x0C; break;
+-	case CMD_PATTERNBREAK:		command = 0x0D; param = ((param / 10) << 4) | (param % 10); break;
+-	case CMD_MODCMDEX:			command = 0x0E; break;
+-	case CMD_SPEED:				command = 0x0F; if (param > 0x20) param = 0x20; break;
+-	case CMD_TEMPO:				if (param > 0x20) { command = 0x0F; break; } return 0;
+-	case CMD_GLOBALVOLUME:		command = 'G' - 55; break;
+-	case CMD_GLOBALVOLSLIDE:	command = 'H' - 55; break;
+-	case CMD_KEYOFF:			command = 'K' - 55; break;
+-	case CMD_SETENVPOSITION:	command = 'L' - 55; break;
+-	case CMD_CHANNELVOLUME:		command = 'M' - 55; break;
+-	case CMD_CHANNELVOLSLIDE:	command = 'N' - 55; break;
+-	case CMD_PANNINGSLIDE:		command = 'P' - 55; break;
+-	case CMD_RETRIG:			command = 'R' - 55; break;
+-	case CMD_TREMOR:			command = 'T' - 55; break;
+-	case CMD_XFINEPORTAUPDOWN:	command = 'X' - 55; break;
+-	case CMD_PANBRELLO:			command = 'Y' - 55; break;
+-	case CMD_MIDI:				command = 'Z' - 55; break;
+-	case CMD_S3MCMDEX:
+-		switch(param & 0xF0)
+-		{
+-		case 0x10:	command = 0x0E; param = (param & 0x0F) | 0x30; break;
+-		case 0x20:	command = 0x0E; param = (param & 0x0F) | 0x50; break;
+-		case 0x30:	command = 0x0E; param = (param & 0x0F) | 0x40; break;
+-		case 0x40:	command = 0x0E; param = (param & 0x0F) | 0x70; break;
+-		case 0x90:	command = 'X' - 55; break;
+-		case 0xB0:	command = 0x0E; param = (param & 0x0F) | 0x60; break;
+-		case 0xA0:
+-		case 0x50:
+-		case 0x70:
+-		case 0x60:	command = param = 0; break;
+-		default:	command = 0x0E; break;
+-		}
+-		break;
+-	default:		command = param = 0;
+-	}
+-	return (WORD)((command << 8) | (param));
+-}
+-
+-
+-#pragma pack(1)
+-
+-typedef struct _MODSAMPLE
+-{
+-	CHAR name[22];
+-	WORD length;
+-	BYTE finetune;
+-	BYTE volume;
+-	WORD loopstart;
+-	WORD looplen;
+-} MODSAMPLE, *PMODSAMPLE;
+-
+-typedef struct _MODMAGIC
+-{
+-	BYTE nOrders;
+-	BYTE nRestartPos;
+-	BYTE Orders[128];
+-        char Magic[4];          // changed from CHAR
+-} MODMAGIC, *PMODMAGIC;
+-
+-#pragma pack()
+-
+-BOOL IsMagic(LPCSTR s1, LPCSTR s2)
+-{
+-	return ((*(DWORD *)s1) == (*(DWORD *)s2)) ? TRUE : FALSE;
+-}
+-
+-
+-BOOL CSoundFile::ReadMod(const BYTE *lpStream, DWORD dwMemLength)
+-//---------------------------------------------------------------
+-{
+-        char s[1024];          // changed from CHAR
+-	DWORD dwMemPos, dwTotalSampleLen;
+-	PMODMAGIC pMagic;
+-	UINT nErr;
+-
+-	if ((!lpStream) || (dwMemLength < 0x600)) return FALSE;
+-	dwMemPos = 20;
+-	m_nSamples = 31;
+-	m_nChannels = 4;
+-	pMagic = (PMODMAGIC)(lpStream+dwMemPos+sizeof(MODSAMPLE)*31);
+-	// Check Mod Magic
+-	memcpy(s, pMagic->Magic, 4);
+-	if ((IsMagic(s, "M.K.")) || (IsMagic(s, "M!K!"))
+-	 || (IsMagic(s, "M&K!")) || (IsMagic(s, "N.T."))) m_nChannels = 4; else
+-	if ((IsMagic(s, "CD81")) || (IsMagic(s, "OKTA"))) m_nChannels = 8; else
+-	if ((s[0]=='F') && (s[1]=='L') && (s[2]=='T') && (s[3]>='4') && (s[3]<='9')) m_nChannels = s[3] - '0'; else
+-	if ((s[0]>='4') && (s[0]<='9') && (s[1]=='C') && (s[2]=='H') && (s[3]=='N')) m_nChannels = s[0] - '0'; else
+-	if ((s[0]=='1') && (s[1]>='0') && (s[1]<='9') && (s[2]=='C') && (s[3]=='H')) m_nChannels = s[1] - '0' + 10; else
+-	if ((s[0]=='2') && (s[1]>='0') && (s[1]<='9') && (s[2]=='C') && (s[3]=='H')) m_nChannels = s[1] - '0' + 20; else
+-	if ((s[0]=='3') && (s[1]>='0') && (s[1]<='2') && (s[2]=='C') && (s[3]=='H')) m_nChannels = s[1] - '0' + 30; else
+-	if ((s[0]=='T') && (s[1]=='D') && (s[2]=='Z') && (s[3]>='4') && (s[3]<='9')) m_nChannels = s[3] - '0'; else
+-	if (IsMagic(s,"16CN")) m_nChannels = 16; else
+-	if (IsMagic(s,"32CN")) m_nChannels = 32; else m_nSamples = 15;
+-	// Load Samples
+-	nErr = 0;
+-	dwTotalSampleLen = 0;
+-	for	(UINT i=1; i<=m_nSamples; i++)
+-	{
+-		PMODSAMPLE pms = (PMODSAMPLE)(lpStream+dwMemPos);
+-		MODINSTRUMENT *psmp = &Ins[i];
+-		UINT loopstart, looplen;
+-
+-		memcpy(m_szNames[i], pms->name, 22);
+-		m_szNames[i][22] = 0;
+-		psmp->uFlags = 0;
+-		psmp->nLength = bswapBE16(pms->length)*2;
+-		dwTotalSampleLen += psmp->nLength;
+-		psmp->nFineTune = MOD2XMFineTune(pms->finetune & 0x0F);
+-		psmp->nVolume = 4*pms->volume;
+-		if (psmp->nVolume > 256) { psmp->nVolume = 256; nErr++; }
+-		psmp->nGlobalVol = 64;
+-		psmp->nPan = 128;
+-		loopstart = bswapBE16(pms->loopstart)*2;
+-		looplen = bswapBE16(pms->looplen)*2;
+-		// Fix loops
+-		if ((looplen > 2) && (loopstart+looplen > psmp->nLength)
+-		 && (loopstart/2+looplen <= psmp->nLength))
+-		{
+-			loopstart /= 2;
+-		}
+-		psmp->nLoopStart = loopstart;
+-		psmp->nLoopEnd = loopstart + looplen;
+-		if (psmp->nLength < 2) psmp->nLength = 0;
+-		if (psmp->nLength)
+-		{
+-			UINT derr = 0;
+-			if (psmp->nLoopStart >= psmp->nLength) { psmp->nLoopStart = psmp->nLength-1; derr|=1; }
+-			if (psmp->nLoopEnd > psmp->nLength) { psmp->nLoopEnd = psmp->nLength; derr |= 1; }
+-			if (psmp->nLoopStart > psmp->nLoopEnd) derr |= 1;
+-			if (psmp->nLoopEnd > psmp->nLoopStart)
+-			{
+-				psmp->uFlags |= CHN_LOOP;
+-			}
+-		}
+-		dwMemPos += sizeof(MODSAMPLE);
+-	}
+-	if ((m_nSamples == 15) && (dwTotalSampleLen > dwMemLength * 4)) return FALSE;
+-	pMagic = (PMODMAGIC)(lpStream+dwMemPos);
+-	dwMemPos += sizeof(MODMAGIC);
+-	if (m_nSamples == 15) dwMemPos -= 4;
+-	memset(Order, 0,sizeof(Order));
+-	memcpy(Order, pMagic->Orders, 128);
+-
+-	UINT nbp, nbpbuggy, nbpbuggy2, norders;
+-
+-	norders = pMagic->nOrders;
+-	if ((!norders) || (norders > 0x80))
+-	{
+-		norders = 0x80;
+-		while ((norders > 1) && (!Order[norders-1])) norders--;
+-	}
+-	nbpbuggy = 0;
+-	nbpbuggy2 = 0;
+-	nbp = 0;
+-	for (UINT iord=0; iord<128; iord++)
+-	{
+-		UINT i = Order[iord];
+-		if ((i < 0x80) && (nbp <= i))
+-		{
+-			nbp = i+1;
+-			if (iord<norders) nbpbuggy = nbp;
+-		}
+-		if (i >= nbpbuggy2) nbpbuggy2 = i+1;
+-	}
+-	for (UINT iend=norders; iend<MAX_ORDERS; iend++) Order[iend] = 0xFF;
+-	norders--;
+-	m_nRestartPos = pMagic->nRestartPos;
+-	if (m_nRestartPos >= 0x78) m_nRestartPos = 0;
+-	if (m_nRestartPos + 1 >= (UINT)norders) m_nRestartPos = 0;
+-	if (!nbp) return FALSE;
+-	DWORD dwWowTest = dwTotalSampleLen+dwMemPos;
+-	if ((IsMagic(pMagic->Magic, "M.K.")) && (dwWowTest + nbp*8*256 == dwMemLength)) m_nChannels = 8;
+-	if ((nbp != nbpbuggy) && (dwWowTest + nbp*m_nChannels*256 != dwMemLength))
+-	{
+-		if (dwWowTest + nbpbuggy*m_nChannels*256 == dwMemLength) nbp = nbpbuggy;
+-		else nErr += 8;
+-	} else
+-	if ((nbpbuggy2 > nbp) && (dwWowTest + nbpbuggy2*m_nChannels*256 == dwMemLength))
+-	{
+-		nbp = nbpbuggy2;
+-	}
+-	if ((dwWowTest < 0x600) || (dwWowTest > dwMemLength)) nErr += 8;
+-	if ((m_nSamples == 15) && (nErr >= 16)) return FALSE;
+-	// Default settings	
+-	m_nType = MOD_TYPE_MOD;
+-	m_nDefaultSpeed = 6;
+-	m_nDefaultTempo = 125;
+-	m_nMinPeriod = 14 << 2;
+-	m_nMaxPeriod = 3424 << 2;
+-	memcpy(m_szNames, lpStream, 20);
+-	// Setting channels pan
+-	for (UINT ich=0; ich<m_nChannels; ich++)
+-	{
+-		ChnSettings[ich].nVolume = 64;
+-		ChnSettings[ich].nPan = (((ich&3)==1) || ((ich&3)==2)) ? 256 : 0;
+-	}
+-	m_nStereoSeparation = (gdwSoundSetup & SNDMIX_MAXDEFAULTPAN) ? 128 : 64;
+-	
+-	// Reading channels
+-	for (UINT ipat=0; ipat<nbp; ipat++)
+-	{
+-		if (ipat < MAX_PATTERNS)
+-		{
+-			if ((Patterns[ipat] = AllocatePattern(64, m_nChannels)) == NULL) break;
+-			PatternSize[ipat] = 64;
+-			PatternAllocSize[ipat] = 64;
+-			if (dwMemPos + m_nChannels*256 >= dwMemLength) break;
+-			MODCOMMAND *m = Patterns[ipat];
+-			LPCBYTE p = lpStream + dwMemPos;
+-			for (UINT j=m_nChannels*64; j; m++,p+=4,j--)
+-			{
+-				BYTE A0=p[0], A1=p[1], A2=p[2], A3=p[3];
+-				UINT n = ((((UINT)A0 & 0x0F) << 8) | (A1));
+-				if ((n) && (n != 0xFFF)) m->note = GetNoteFromPeriod(n << 2);
+-				m->instr = ((UINT)A2 >> 4) | (A0 & 0x10);
+-				m->command = A2 & 0x0F;
+-				m->param = A3;
+-				if ((m->command) || (m->param)) ConvertModCommand(m);
+-			}
+-		}
+-		dwMemPos += m_nChannels*256;
+-	}
+-	// Reading instruments
+-	DWORD dwErrCheck = 0;
+-	for (UINT ismp=1; ismp<=m_nSamples; ismp++) if (Ins[ismp].nLength)
+-	{
+-		LPSTR p = (LPSTR)(lpStream+dwMemPos);
+-		UINT flags = 0;
+-		if (dwMemPos + 5 >= dwMemLength) break;
+-		if (!strnicmp(p, "ADPCM", 5))
+-		{
+-			flags = 3;
+-			p += 5;
+-			dwMemPos += 5;
+-		}
+-		DWORD dwSize = ReadSample(&Ins[ismp], flags, p, dwMemLength - dwMemPos);
+-		if (dwSize)
+-		{
+-			dwMemPos += dwSize;
+-			dwErrCheck++;
+-		}
+-	}
+-#ifdef MODPLUG_TRACKER
+-	return TRUE;
+-#else
+-	return (dwErrCheck) ? TRUE : FALSE;
+-#endif
+-}
+-
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_mt2.cxx audacious-plugins-2.5.4/src/modplug/load_mt2.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_mt2.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_mt2.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,637 +0,0 @@
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#define MT2DEBUG
+-
+-#pragma pack(1)
+-
+-typedef struct _MT2FILEHEADER
+-{
+-	DWORD dwMT20;	// 0x3032544D "MT20"
+-	DWORD dwSpecial;
+-	WORD wVersion;
+-	CHAR szTrackerName[32];	// "MadTracker 2.0"
+-	CHAR szSongName[64];
+-	WORD nOrders;
+-	WORD wRestart;
+-	WORD wPatterns;
+-	WORD wChannels;
+-	WORD wSamplesPerTick;
+-	BYTE bTicksPerLine;
+-	BYTE bLinesPerBeat;
+-	DWORD fulFlags; // b0=packed patterns
+-	WORD wInstruments;
+-	WORD wSamples;
+-	BYTE Orders[256];
+-} MT2FILEHEADER;
+-
+-typedef struct _MT2PATTERN
+-{
+-	WORD wLines;
+-	DWORD wDataLen;
+-} MT2PATTERN;
+-
+-typedef struct _MT2COMMAND
+-{
+-	BYTE note;	// 0=nothing, 97=note off
+-	BYTE instr;
+-	BYTE vol;
+-	BYTE pan;
+-	BYTE fxcmd;
+-	BYTE fxparam1;
+-	BYTE fxparam2;
+-} MT2COMMAND;
+-
+-typedef struct _MT2DRUMSDATA
+-{
+-	WORD wDrumPatterns;
+-	WORD wDrumSamples[8];
+-	BYTE DrumPatternOrder[256];
+-} MT2DRUMSDATA;
+-
+-typedef struct _MT2AUTOMATION
+-{
+-	DWORD dwFlags;
+-	DWORD dwEffectId;
+-	DWORD nEnvPoints;
+-} MT2AUTOMATION;
+-
+-typedef struct _MT2INSTRUMENT
+-{
+-	CHAR szName[32];
+-	DWORD dwDataLen;
+-	WORD wSamples;
+-	BYTE GroupsMapping[96];
+-	BYTE bVibType;
+-	BYTE bVibSweep;
+-	BYTE bVibDepth;
+-	BYTE bVibRate;
+-	WORD wFadeOut;
+-	WORD wNNA;
+-	WORD wInstrFlags;
+-	WORD wEnvFlags1;
+-	WORD wEnvFlags2;
+-} MT2INSTRUMENT;
+-
+-typedef struct _MT2ENVELOPE
+-{
+-	BYTE nFlags;
+-	BYTE nPoints;
+-	BYTE nSustainPos;
+-	BYTE nLoopStart;
+-	BYTE nLoopEnd;
+-	BYTE bReserved[3];
+-	BYTE EnvData[64];
+-} MT2ENVELOPE;
+-
+-typedef struct _MT2SYNTH
+-{
+-	BYTE nSynthId;
+-	BYTE nFxId;
+-	WORD wCutOff;
+-	BYTE nResonance;
+-	BYTE nAttack;
+-	BYTE nDecay;
+-	BYTE bReserved[25];
+-} MT2SYNTH;
+-
+-typedef struct _MT2SAMPLE
+-{
+-	CHAR szName[32];
+-	DWORD dwDataLen;
+-	DWORD dwLength;
+-	DWORD dwFrequency;
+-	BYTE nQuality;
+-	BYTE nChannels;
+-	BYTE nFlags;
+-	BYTE nLoop;
+-	DWORD dwLoopStart;
+-	DWORD dwLoopEnd;
+-	WORD wVolume;
+-	BYTE nPan;
+-	BYTE nBaseNote;
+-	WORD wSamplesPerBeat;
+-} MT2SAMPLE;
+-
+-typedef struct _MT2GROUP
+-{
+-	BYTE nSmpNo;
+-	BYTE nVolume;	// 0-128
+-	BYTE nFinePitch;
+-	BYTE Reserved[5];
+-} MT2GROUP;
+-
+-#pragma pack()
+-
+-
+-static VOID ConvertMT2Command(CSoundFile *that, MODCOMMAND *m, MT2COMMAND *p)
+-//---------------------------------------------------------------------------
+-{
+-	// Note
+-	m->note = 0;
+-	if (p->note) m->note = (p->note > 96) ? 0xFF : p->note+12;
+-	// Instrument
+-	m->instr = p->instr;
+-	// Volume Column
+-	if ((p->vol >= 0x10) && (p->vol <= 0x90))
+-	{
+-		m->volcmd = VOLCMD_VOLUME;
+-		m->vol = (p->vol - 0x10) >> 1;
+-	} else
+-	if ((p->vol >= 0xA0) && (p->vol <= 0xAF))
+-	{
+-		m->volcmd = VOLCMD_VOLSLIDEDOWN;
+-		m->vol = (p->vol & 0x0f);
+-	} else
+-	if ((p->vol >= 0xB0) && (p->vol <= 0xBF))
+-	{
+-		m->volcmd = VOLCMD_VOLSLIDEUP;
+-		m->vol = (p->vol & 0x0f);
+-	} else
+-	if ((p->vol >= 0xC0) && (p->vol <= 0xCF))
+-	{
+-		m->volcmd = VOLCMD_FINEVOLDOWN;
+-		m->vol = (p->vol & 0x0f);
+-	} else
+-	if ((p->vol >= 0xD0) && (p->vol <= 0xDF))
+-	{
+-		m->volcmd = VOLCMD_FINEVOLUP;
+-		m->vol = (p->vol & 0x0f);
+-	} else
+-	{
+-		m->volcmd = 0;
+-		m->vol = 0;
+-	}
+-	// Effects
+-	m->command = 0;
+-	m->param = 0;
+-	if ((p->fxcmd) || (p->fxparam1) || (p->fxparam2))
+-	{
+-		if (!p->fxcmd)
+-		{
+-			m->command = p->fxparam2;
+-			m->param = p->fxparam1;
+-			that->ConvertModCommand(m);
+-		} else
+-		{
+-			// TODO: MT2 Effects
+-		}
+-	}
+-}
+-
+-
+-BOOL CSoundFile::ReadMT2(LPCBYTE lpStream, DWORD dwMemLength)
+-//-----------------------------------------------------------
+-{
+-	MT2FILEHEADER *pfh = (MT2FILEHEADER *)lpStream;
+-	DWORD dwMemPos, dwDrumDataPos, dwExtraDataPos;
+-	UINT nDrumDataLen, nExtraDataLen;
+-	MT2DRUMSDATA *pdd;
+-	MT2INSTRUMENT *InstrMap[255];
+-	MT2SAMPLE *SampleMap[256];
+-
+-	if ((!lpStream) || (dwMemLength < sizeof(MT2FILEHEADER))
+-	 || (pfh->dwMT20 != 0x3032544D)
+-	 || (pfh->wVersion < 0x0200) || (pfh->wVersion >= 0x0300)
+-	 || (pfh->wChannels < 4) || (pfh->wChannels > 64)) return FALSE;
+-	pdd = NULL;
+-	m_nType = MOD_TYPE_MT2;
+-	m_nChannels = pfh->wChannels;
+-	m_nRestartPos = pfh->wRestart;
+-	m_nDefaultSpeed = pfh->bTicksPerLine;
+-	m_nDefaultTempo = 125;
+-	if ((pfh->wSamplesPerTick > 100) && (pfh->wSamplesPerTick < 5000))
+-	{
+-		m_nDefaultTempo = 110250 / pfh->wSamplesPerTick;
+-	}
+-	for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
+-	{
+-		Order[iOrd] = (BYTE)((iOrd < pfh->nOrders) ? pfh->Orders[iOrd] : 0xFF);
+-	}
+-	memcpy(m_szNames[0], pfh->szSongName, 32);
+-	m_szNames[0][31] = 0;
+-	dwMemPos = sizeof(MT2FILEHEADER);
+-	nDrumDataLen = *(WORD *)(lpStream + dwMemPos);
+-	dwDrumDataPos = dwMemPos + 2;
+-	if (nDrumDataLen >= 2) pdd = (MT2DRUMSDATA *)(lpStream+dwDrumDataPos);
+-	dwMemPos += 2 + nDrumDataLen;
+-#ifdef MT2DEBUG
+-
+-	Log("MT2 v%03X: \"%s\" (flags=%04X)\n", pfh->wVersion, m_szNames[0], pfh->fulFlags);
+-	Log("%d Channels, %d Patterns, %d Instruments, %d Samples\n", pfh->wChannels, pfh->wPatterns, pfh->wInstruments, pfh->wSamples);
+-	Log("Drum Data: %d bytes @%04X\n", nDrumDataLen, dwDrumDataPos);
+-#endif
+-	if (dwMemPos >= dwMemLength-12) return TRUE;
+-	if (!*(DWORD *)(lpStream+dwMemPos)) dwMemPos += 4;
+-	if (!*(DWORD *)(lpStream+dwMemPos)) dwMemPos += 4;
+-	nExtraDataLen = *(DWORD *)(lpStream+dwMemPos);
+-	dwExtraDataPos = dwMemPos + 4;
+-	dwMemPos += 4;
+-#ifdef MT2DEBUG
+-	Log("Extra Data: %d bytes @%04X\n", nExtraDataLen, dwExtraDataPos);
+-#endif
+-	if (dwMemPos + nExtraDataLen >= dwMemLength) return TRUE;
+-	while (dwMemPos+8 < dwExtraDataPos + nExtraDataLen)
+-	{
+-		DWORD dwId = *(DWORD *)(lpStream+dwMemPos);
+-		DWORD dwLen = *(DWORD *)(lpStream+dwMemPos+4);
+-		dwMemPos += 8;
+-		if (dwMemPos + dwLen > dwMemLength) return TRUE;
+-#ifdef MT2DEBUG
+-		CHAR s[5];
+-		memcpy(s, &dwId, 4);
+-		s[4] = 0;
+-		Log("pos=0x%04X: %s: %d bytes\n", dwMemPos-8, s, dwLen);
+-#endif
+-		switch(dwId)
+-		{
+-		// MSG
+-		case 0x0047534D:
+-			if ((dwLen > 3) && (!m_lpszSongComments))
+-			{
+-				DWORD nTxtLen = dwLen;
+-				if (nTxtLen > 32000) nTxtLen = 32000;
+-				m_lpszSongComments = new char[nTxtLen];  // changed from CHAR
+-				if (m_lpszSongComments)
+-				{
+-					memcpy(m_lpszSongComments, lpStream+dwMemPos+1, nTxtLen-1);
+-					m_lpszSongComments[nTxtLen-1] = 0;
+-				}
+-			}
+-			break;
+-		// SUM -> author name (or "Unregistered")
+-		// TMAP
+-		// TRKS
+-		case 0x534b5254:
+-			break;
+-		}
+-		dwMemPos += dwLen;
+-	}
+-	// Load Patterns
+-	dwMemPos = dwExtraDataPos + nExtraDataLen;
+-	for (UINT iPat=0; iPat<pfh->wPatterns; iPat++) if (dwMemPos < dwMemLength-6)
+-	{
+-		MT2PATTERN *pmp = (MT2PATTERN *)(lpStream+dwMemPos);
+-		UINT wDataLen = (pmp->wDataLen + 1) & ~1;
+-		dwMemPos += 6;
+-		if (dwMemPos + wDataLen > dwMemLength) break;
+-		UINT nLines = pmp->wLines;
+-		if ((iPat < MAX_PATTERNS) && (nLines > 0) && (nLines <= 256))
+-		{
+-	#ifdef MT2DEBUG
+-			Log("Pattern #%d @%04X: %d lines, %d bytes\n", iPat, dwMemPos-6, nLines, pmp->wDataLen);
+-	#endif
+-			PatternSize[iPat] = nLines;
+-			PatternAllocSize[iPat] = nLines;
+-			Patterns[iPat] = AllocatePattern(nLines, m_nChannels);
+-			if (!Patterns[iPat]) return TRUE;
+-			MODCOMMAND *m = Patterns[iPat];
+-			UINT len = wDataLen;
+-			if (pfh->fulFlags & 1) // Packed Patterns
+-			{
+-				BYTE *p = (BYTE *)(lpStream+dwMemPos);
+-				UINT pos = 0, row=0, ch=0;
+-				while (pos < len)
+-				{
+-					MT2COMMAND cmd;
+-					UINT infobyte = p[pos++];
+-					UINT rptcount = 0;
+-					if (infobyte == 0xff)
+-					{
+-						rptcount = p[pos++];
+-						infobyte = p[pos++];
+-				#if 0
+-						Log("(%d.%d) FF(%02X).%02X\n", row, ch, rptcount, infobyte);
+-					} else
+-					{
+-						Log("(%d.%d) %02X\n", row, ch, infobyte);
+-				#endif
+-					}
+-					if (infobyte & 0x7f)
+-					{
+-						UINT patpos = row*m_nChannels+ch;
+-						cmd.note = cmd.instr = cmd.vol = cmd.pan = cmd.fxcmd = cmd.fxparam1 = cmd.fxparam2 = 0;
+-						if (infobyte & 1) cmd.note = p[pos++];
+-						if (infobyte & 2) cmd.instr = p[pos++];
+-						if (infobyte & 4) cmd.vol = p[pos++];
+-						if (infobyte & 8) cmd.pan = p[pos++];
+-						if (infobyte & 16) cmd.fxcmd = p[pos++];
+-						if (infobyte & 32) cmd.fxparam1 = p[pos++];
+-						if (infobyte & 64) cmd.fxparam2 = p[pos++];
+-					#ifdef MT2DEBUG
+-						if (cmd.fxcmd)
+-						{
+-							Log("(%d.%d) MT2 FX=%02X.%02X.%02X\n", row, ch, cmd.fxcmd, cmd.fxparam1, cmd.fxparam2);
+-						}
+-					#endif
+-						ConvertMT2Command(this, &m[patpos], &cmd);
+-					}
+-					row += rptcount+1;
+-					while (row >= nLines) { row-=nLines; ch++; }
+-					if (ch >= m_nChannels) break;
+-				}
+-			} else
+-			{
+-				MT2COMMAND *p = (MT2COMMAND *)(lpStream+dwMemPos);
+-				UINT n = 0;
+-				while ((len > sizeof(MT2COMMAND)) && (n < m_nChannels*nLines))
+-				{
+-					ConvertMT2Command(this, m, p);
+-					len -= sizeof(MT2COMMAND);
+-					n++;
+-					p++;
+-					m++;
+-				}
+-			}
+-		}
+-		dwMemPos += wDataLen;
+-	}
+-	// Skip Drum Patterns
+-	if (pdd)
+-	{
+-	#ifdef MT2DEBUG
+-		Log("%d Drum Patterns at offset 0x%08X\n", pdd->wDrumPatterns, dwMemPos);
+-	#endif
+-		for (UINT iDrm=0; iDrm<pdd->wDrumPatterns; iDrm++)
+-		{
+-			if (dwMemPos > dwMemLength-2) return TRUE;
+-			UINT nLines = *(WORD *)(lpStream+dwMemPos);
+-		#ifdef MT2DEBUG
+-			if (nLines != 64) Log("Drum Pattern %d: %d Lines @%04X\n", iDrm, nLines, dwMemPos);
+-		#endif
+-			dwMemPos += 2 + nLines * 32;
+-		}
+-	}
+-	// Automation
+-	if (pfh->fulFlags & 2)
+-	{
+-	#ifdef MT2DEBUG
+-		Log("Automation at offset 0x%08X\n", dwMemPos);
+-	#endif
+-		UINT nAutoCount = m_nChannels;
+-		if (pfh->fulFlags & 0x10) nAutoCount++; // Master Automation
+-		if ((pfh->fulFlags & 0x08) && (pdd)) nAutoCount += 8; // Drums Automation
+-		nAutoCount *= pfh->wPatterns;
+-		for (UINT iAuto=0; iAuto<nAutoCount; iAuto++)
+-		{
+-			if (dwMemPos+12 >= dwMemLength) return TRUE;
+-			MT2AUTOMATION *pma = (MT2AUTOMATION *)(lpStream+dwMemPos);
+-			dwMemPos += (pfh->wVersion <= 0x201) ? 4 : 8;
+-			for (UINT iEnv=0; iEnv<14; iEnv++)
+-			{
+-				if (pma->dwFlags & (1 << iEnv))
+-				{
+-				#ifdef MT2DEBUG
+-					UINT nPoints = *(DWORD *)(lpStream+dwMemPos);
+-					Log("  Env[%d/%d] %04X @%04X: %d points\n", iAuto, nAutoCount, 1 << iEnv, dwMemPos-8, nPoints);
+-				#endif
+-					dwMemPos += 260;
+-				}
+-			}
+-		}
+-	}
+-	// Load Instruments
+-#ifdef MT2DEBUG
+-	Log("Loading instruments at offset 0x%08X\n", dwMemPos);
+-#endif
+-	memset(InstrMap, 0, sizeof(InstrMap));
+-	m_nInstruments = (pfh->wInstruments < MAX_INSTRUMENTS) ? pfh->wInstruments : MAX_INSTRUMENTS-1;
+-	m_dwSongFlags |= SONG_INSTRUMENTMODE;
+-	for (UINT iIns=1; iIns<=255; iIns++)
+-	{
+-		if (dwMemPos+36 > dwMemLength) return TRUE;
+-		MT2INSTRUMENT *pmi = (MT2INSTRUMENT *)(lpStream+dwMemPos);
+-		INSTRUMENTHEADER *penv = NULL;
+-		if (iIns <= m_nInstruments)
+-		{
+-			penv = new INSTRUMENTHEADER;
+-			Headers[iIns] = penv;
+-			if (penv)
+-			{
+-				memset(penv, 0, sizeof(INSTRUMENTHEADER));
+-				memcpy(penv->name, pmi->szName, 32);
+-				penv->nGlobalVol = 128;
+-				penv->nPan = 128;
+-				for (UINT i=0; i<120; i++)
+-				{
+-					penv->NoteMap[i] = i+1;
+-				}
+-			}
+-		}
+-	#ifdef MT2DEBUG
+-		if (iIns <= pfh->wInstruments) Log("  Instrument #%d at offset %04X: %d bytes\n", iIns, dwMemPos, pmi->dwDataLen);
+-	#endif
+-		if (((LONG)pmi->dwDataLen > 0) && (dwMemPos + pmi->dwDataLen + 40 <= dwMemLength))
+-		{
+-			InstrMap[iIns-1] = pmi;
+-			if (penv)
+-			{
+-				penv->nFadeOut = pmi->wFadeOut;
+-				penv->nNNA = pmi->wNNA & 3;
+-				penv->nDCT = (pmi->wNNA>>8) & 3;
+-				penv->nDNA = (pmi->wNNA>>12) & 3;
+-				MT2ENVELOPE *pehdr[4];
+-				WORD *pedata[4];
+-				if (pfh->wVersion <= 0x201)
+-				{
+-					DWORD dwEnvPos = dwMemPos + sizeof(MT2INSTRUMENT) - 4;
+-					pehdr[0] = (MT2ENVELOPE *)(lpStream+dwEnvPos);
+-					pehdr[1] = (MT2ENVELOPE *)(lpStream+dwEnvPos+8);
+-					pehdr[2] = pehdr[3] = NULL;
+-					pedata[0] = (WORD *)(lpStream+dwEnvPos+16);
+-					pedata[1] = (WORD *)(lpStream+dwEnvPos+16+64);
+-					pedata[2] = pedata[3] = NULL;
+-				} else
+-				{
+-					DWORD dwEnvPos = dwMemPos + sizeof(MT2INSTRUMENT);
+-					for (UINT i=0; i<4; i++)
+-					{
+-						if (pmi->wEnvFlags1 & (1<<i))
+-						{
+-							pehdr[i] = (MT2ENVELOPE *)(lpStream+dwEnvPos);
+-							pedata[i] = (WORD *)pehdr[i]->EnvData;
+-							dwEnvPos += sizeof(MT2ENVELOPE);
+-						} else
+-						{
+-							pehdr[i] = NULL;
+-							pedata[i] = NULL;
+-						}
+-					}
+-				}
+-				// Load envelopes
+-				for (UINT iEnv=0; iEnv<4; iEnv++) if (pehdr[iEnv])
+-				{
+-					MT2ENVELOPE *pme = pehdr[iEnv];
+-					int *pEnvPoints = NULL;
+-					BYTE *pEnvData = NULL;
+-				#ifdef MT2DEBUG
+-					Log("  Env %d.%d @%04X: %d points\n", iIns, iEnv, (UINT)(((BYTE *)pme)-lpStream), pme->nPoints);
+-				#endif
+-					switch(iEnv)
+-					{
+-					// Volume Envelope
+-					case 0:
+-						if (pme->nFlags & 1) penv->dwFlags |= ENV_VOLUME;
+-						if (pme->nFlags & 2) penv->dwFlags |= ENV_VOLSUSTAIN;
+-						if (pme->nFlags & 4) penv->dwFlags |= ENV_VOLLOOP;
+-						penv->VolEnv.nNodes = (pme->nPoints > 16) ? 16 : pme->nPoints;
+-						penv->VolEnv.nSustainStart = penv->VolEnv.nSustainEnd = pme->nSustainPos;
+-						penv->VolEnv.nLoopStart = pme->nLoopStart;
+-						penv->VolEnv.nLoopEnd = pme->nLoopEnd;
+-						pEnvPoints = penv->VolEnv.Ticks;
+-						pEnvData = penv->VolEnv.Values;
+-						break;
+-
+-					// Panning Envelope
+-					case 1:
+-						if (pme->nFlags & 1) penv->dwFlags |= ENV_PANNING;
+-						if (pme->nFlags & 2) penv->dwFlags |= ENV_PANSUSTAIN;
+-						if (pme->nFlags & 4) penv->dwFlags |= ENV_PANLOOP;
+-						penv->PanEnv.nNodes = (pme->nPoints > 16) ? 16 : pme->nPoints;
+-						penv->PanEnv.nSustainStart = penv->PanEnv.nSustainEnd = pme->nSustainPos;
+-						penv->PanEnv.nLoopStart = pme->nLoopStart;
+-						penv->PanEnv.nLoopEnd = pme->nLoopEnd;
+-						pEnvPoints = penv->PanEnv.Ticks;
+-						pEnvData = penv->PanEnv.Values;
+-						break;
+-
+-					// Pitch/Filter envelope
+-					default:
+-						if (pme->nFlags & 1) penv->dwFlags |= (iEnv==3) ? (ENV_PITCH|ENV_FILTER) : ENV_PITCH;
+-						if (pme->nFlags & 2) penv->dwFlags |= ENV_PITCHSUSTAIN;
+-						if (pme->nFlags & 4) penv->dwFlags |= ENV_PITCHLOOP;
+-						penv->PitchEnv.nNodes = (pme->nPoints > 16) ? 16 : pme->nPoints;
+-						penv->PitchEnv.nSustainStart = penv->PitchEnv.nSustainEnd = pme->nSustainPos;
+-						penv->PitchEnv.nLoopStart = pme->nLoopStart;
+-						penv->PitchEnv.nLoopEnd = pme->nLoopEnd;
+-						pEnvPoints = penv->PitchEnv.Ticks;
+-						pEnvData = penv->PitchEnv.Values;
+-					}
+-					// Envelope data
+-					if ((pEnvPoints) && (pEnvData) && (pedata[iEnv]))
+-					{
+-						WORD *psrc = pedata[iEnv];
+-						for (UINT i=0; i<16; i++)
+-						{
+-							pEnvPoints[i] = psrc[i*2];
+-							pEnvData[i] = (BYTE)psrc[i*2+1];
+-						}
+-					}
+-				}
+-			}
+-			dwMemPos += pmi->dwDataLen + 36;
+-			if (pfh->wVersion > 0x201) dwMemPos += 4; // ?
+-		} else
+-		{
+-			dwMemPos += 36;
+-		}
+-	}
+-#ifdef MT2DEBUG
+-	Log("Loading samples at offset 0x%08X\n", dwMemPos);
+-#endif
+-	memset(SampleMap, 0, sizeof(SampleMap));
+-	m_nSamples = (pfh->wSamples < MAX_SAMPLES) ? pfh->wSamples : MAX_SAMPLES-1;
+-	for (UINT iSmp=1; iSmp<=256; iSmp++)
+-	{
+-		if (dwMemPos+36 > dwMemLength) return TRUE;
+-		MT2SAMPLE *pms = (MT2SAMPLE *)(lpStream+dwMemPos);
+-	#ifdef MT2DEBUG
+-		if (iSmp <= m_nSamples) Log("  Sample #%d at offset %04X: %d bytes\n", iSmp, dwMemPos, pms->dwDataLen);
+-	#endif
+-		if (iSmp < MAX_SAMPLES)
+-		{
+-			memcpy(m_szNames[iSmp], pms->szName, 32);
+-		}
+-		if (pms->dwDataLen > 0)
+-		{
+-			SampleMap[iSmp-1] = pms;
+-			if (iSmp < MAX_SAMPLES)
+-			{
+-				MODINSTRUMENT *psmp = &Ins[iSmp];
+-				psmp->nGlobalVol = 64;
+-				psmp->nVolume = (pms->wVolume >> 7);
+-				psmp->nPan = (pms->nPan == 0x80) ? 128 : (pms->nPan^0x80);
+-				psmp->nLength = pms->dwLength;
+-				psmp->nC4Speed = pms->dwFrequency;
+-				psmp->nLoopStart = pms->dwLoopStart;
+-				psmp->nLoopEnd = pms->dwLoopEnd;
+-				FrequencyToTranspose(psmp);
+-				psmp->RelativeTone -= pms->nBaseNote - 49;
+-				psmp->nC4Speed = TransposeToFrequency(psmp->RelativeTone, psmp->nFineTune);
+-				if (pms->nQuality == 2) { psmp->uFlags |= CHN_16BIT; psmp->nLength >>= 1; }
+-				if (pms->nChannels == 2) { psmp->nLength >>= 1; }
+-				if (pms->nLoop == 1) psmp->uFlags |= CHN_LOOP;
+-				if (pms->nLoop == 2) psmp->uFlags |= CHN_LOOP|CHN_PINGPONGLOOP;
+-			}
+-			dwMemPos += pms->dwDataLen + 36;
+-		} else
+-		{
+-			dwMemPos += 36;
+-		}
+-	}
+-#ifdef MT2DEBUG
+-	Log("Loading groups at offset 0x%08X\n", dwMemPos);
+-#endif
+-	for (UINT iMap=0; iMap<255; iMap++) if (InstrMap[iMap])
+-	{
+-		if (dwMemPos+8 > dwMemLength) return TRUE;
+-		MT2INSTRUMENT *pmi = InstrMap[iMap];
+-		INSTRUMENTHEADER *penv = NULL;
+-		if (iMap<m_nInstruments) penv = Headers[iMap+1];
+-		for (UINT iGrp=0; iGrp<pmi->wSamples; iGrp++)
+-		{
+-			if (penv)
+-			{
+-				MT2GROUP *pmg = (MT2GROUP *)(lpStream+dwMemPos);
+-				for (UINT i=0; i<96; i++)
+-				{
+-					if (pmi->GroupsMapping[i] == iGrp)
+-					{
+-						UINT nSmp = pmg->nSmpNo+1;
+-						penv->Keyboard[i+12] = (BYTE)nSmp;
+-						if (nSmp <= m_nSamples)
+-						{
+-							Ins[nSmp].nVibType = pmi->bVibType;
+-							Ins[nSmp].nVibSweep = pmi->bVibSweep;
+-							Ins[nSmp].nVibDepth = pmi->bVibDepth;
+-							Ins[nSmp].nVibRate = pmi->bVibRate/4;
+-						}
+-					}
+-				}
+-			}
+-			dwMemPos += 8;
+-		}
+-	}
+-#ifdef MT2DEBUG
+-	Log("Loading sample data at offset 0x%08X\n", dwMemPos);
+-#endif
+-	for (UINT iData=0; iData<256; iData++) if ((iData < m_nSamples) && (SampleMap[iData]))
+-	{
+-		MT2SAMPLE *pms = SampleMap[iData];
+-		MODINSTRUMENT *psmp = &Ins[iData+1];
+-		if (!(pms->nFlags & 5))
+-		{
+-			if (psmp->nLength > 0) 
+-			{
+-			#ifdef MT2DEBUG
+-				Log("  Reading sample #%d at offset 0x%04X (len=%d)\n", iData+1, dwMemPos, psmp->nLength);
+-			#endif
+-				UINT rsflags;
+-				
+-				if (pms->nChannels == 2)
+-					rsflags = (psmp->uFlags & CHN_16BIT) ? RS_STPCM16D : RS_STPCM8D;
+-				else
+-					rsflags = (psmp->uFlags & CHN_16BIT) ? RS_PCM16D : RS_PCM8D;
+-
+-				dwMemPos += ReadSample(psmp, rsflags, (LPCSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos);
+-			}
+-		} else
+-		if (dwMemPos+4 < dwMemLength)
+-		{
+-			UINT nNameLen = *(DWORD *)(lpStream+dwMemPos);
+-			dwMemPos += nNameLen + 16;
+-		}
+-		if (dwMemPos+4 >= dwMemLength) break;
+-	}
+-	return TRUE;
+-}
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_mtm.cxx audacious-plugins-2.5.4/src/modplug/load_mtm.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_mtm.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_mtm.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,165 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#pragma warning(disable:4244)
+-
+-//////////////////////////////////////////////////////////
+-// MTM file support (import only)
+-
+-#pragma pack(1)
+-
+-
+-typedef struct tagMTMSAMPLE
+-{
+-        char samplename[22];      // changed from CHAR
+-	DWORD length;
+-	DWORD reppos;
+-	DWORD repend;
+-	CHAR finetune;
+-	BYTE volume;
+-	BYTE attribute;
+-} MTMSAMPLE;
+-
+-
+-typedef struct tagMTMHEADER
+-{
+-	char id[4];	        // MTM file marker + version // changed from CHAR
+-	char songname[20];	// ASCIIZ songname  // changed from CHAR
+-	WORD numtracks;		// number of tracks saved
+-	BYTE lastpattern;	// last pattern number saved
+-	BYTE lastorder;		// last order number to play (songlength-1)
+-	WORD commentsize;	// length of comment field
+-	BYTE numsamples;	// number of samples saved
+-	BYTE attribute;		// attribute byte (unused)
+-	BYTE beatspertrack;
+-	BYTE numchannels;	// number of channels used
+-	BYTE panpos[32];	// voice pan positions
+-} MTMHEADER;
+-
+-
+-#pragma pack()
+-
+-
+-BOOL CSoundFile::ReadMTM(LPCBYTE lpStream, DWORD dwMemLength)
+-//-----------------------------------------------------------
+-{
+-	MTMHEADER *pmh = (MTMHEADER *)lpStream;
+-	DWORD dwMemPos = 66;
+-
+-	if ((!lpStream) || (dwMemLength < 0x100)) return FALSE;
+-	if ((strncmp(pmh->id, "MTM", 3)) || (pmh->numchannels > 32)
+-	 || (pmh->numsamples >= MAX_SAMPLES) || (!pmh->numsamples)
+-	 || (!pmh->numtracks) || (!pmh->numchannels)
+-	 || (!pmh->lastpattern) || (pmh->lastpattern > MAX_PATTERNS)) return FALSE;
+-	strncpy(m_szNames[0], pmh->songname, 20);
+-	m_szNames[0][20] = 0;
+-	if (dwMemPos + 37*pmh->numsamples + 128 + 192*bswapLE16(pmh->numtracks)
+-	 + 64 * (pmh->lastpattern+1) + bswapLE16(pmh->commentsize) >= dwMemLength) return FALSE;
+-	m_nType = MOD_TYPE_MTM;
+-	m_nSamples = pmh->numsamples;
+-	m_nChannels = pmh->numchannels;
+-	// Reading instruments
+-	for	(UINT i=1; i<=m_nSamples; i++)
+-	{
+-		MTMSAMPLE *pms = (MTMSAMPLE *)(lpStream + dwMemPos);
+-		strncpy(m_szNames[i], pms->samplename, 22);
+-		m_szNames[i][22] = 0;
+-		Ins[i].nVolume = pms->volume << 2;
+-		Ins[i].nGlobalVol = 64;
+-		DWORD len = bswapLE32(pms->length);
+-		if ((len > 4) && (len <= MAX_SAMPLE_LENGTH))
+-		{
+-			Ins[i].nLength = len;
+-			Ins[i].nLoopStart = bswapLE32(pms->reppos);
+-			Ins[i].nLoopEnd = bswapLE32(pms->repend);
+-			if (Ins[i].nLoopEnd > Ins[i].nLength) Ins[i].nLoopEnd = Ins[i].nLength;
+-			if (Ins[i].nLoopStart + 4 >= Ins[i].nLoopEnd) Ins[i].nLoopStart = Ins[i].nLoopEnd = 0;
+-			if (Ins[i].nLoopEnd) Ins[i].uFlags |= CHN_LOOP;
+-			Ins[i].nFineTune = MOD2XMFineTune(pms->finetune);
+-			if (pms->attribute & 0x01)
+-			{
+-				Ins[i].uFlags |= CHN_16BIT;
+-				Ins[i].nLength >>= 1;
+-				Ins[i].nLoopStart >>= 1;
+-				Ins[i].nLoopEnd >>= 1;
+-			}
+-			Ins[i].nPan = 128;
+-		}
+-		dwMemPos += 37;
+-	}
+-	// Setting Channel Pan Position
+-	for (UINT ich=0; ich<m_nChannels; ich++)
+-	{
+-		ChnSettings[ich].nPan = ((pmh->panpos[ich] & 0x0F) << 4) + 8;
+-		ChnSettings[ich].nVolume = 64;
+-	}
+-	// Reading pattern order
+-	memcpy(Order, lpStream + dwMemPos, pmh->lastorder+1);
+-	dwMemPos += 128;
+-	// Reading Patterns
+-	LPCBYTE pTracks = lpStream + dwMemPos;
+-	dwMemPos += 192 * bswapLE16(pmh->numtracks);
+-	LPWORD pSeq = (LPWORD)(lpStream + dwMemPos);
+-	for (UINT pat=0; pat<=pmh->lastpattern; pat++)
+-	{
+-		PatternSize[pat] = 64;
+-		PatternAllocSize[pat] = 64;
+-		if ((Patterns[pat] = AllocatePattern(64, m_nChannels)) == NULL) break;
+-		for (UINT n=0; n<32; n++) if ((pSeq[n]) && (pSeq[n] <= bswapLE16(pmh->numtracks)) && (n < m_nChannels))
+-		{
+-			LPCBYTE p = pTracks + 192 * (pSeq[n]-1);
+-			MODCOMMAND *m = Patterns[pat] + n;
+-			for (UINT i=0; i<64; i++, m+=m_nChannels, p+=3)
+-			{
+-				if (p[0] & 0xFC) m->note = (p[0] >> 2) + 37;
+-				m->instr = ((p[0] & 0x03) << 4) | (p[1] >> 4);
+-				UINT cmd = p[1] & 0x0F;
+-				UINT param = p[2];
+-				if (cmd == 0x0A)
+-				{
+-					if (param & 0xF0) param &= 0xF0; else param &= 0x0F;
+-				}
+-				m->command = cmd;
+-				m->param = param;
+-				if ((cmd) || (param)) ConvertModCommand(m);
+-			}
+-		}
+-		pSeq += 32;
+-	}
+-	dwMemPos += 64*(pmh->lastpattern+1);
+-	if (bswapLE16(pmh->commentsize) && (dwMemPos + bswapLE16(pmh->commentsize) < dwMemLength))
+-	{
+-		UINT n = bswapLE16(pmh->commentsize);
+-		m_lpszSongComments = new char[n+1];
+-		if (m_lpszSongComments)
+-		{
+-			memcpy(m_lpszSongComments, lpStream+dwMemPos, n);
+-			m_lpszSongComments[n] = 0;
+-			for (UINT i=0; i<n; i++)
+-			{
+-				if (!m_lpszSongComments[i])
+-				{
+-					m_lpszSongComments[i] = ((i+1) % 40) ? 0x20 : 0x0D;
+-				}
+-			}
+-		}
+-	}
+-	dwMemPos += bswapLE16(pmh->commentsize);
+-	// Reading Samples
+-	for (UINT ismp=1; ismp<=m_nSamples; ismp++)
+-	{
+-		if (dwMemPos >= dwMemLength) break;
+-		dwMemPos += ReadSample(&Ins[ismp], (Ins[ismp].uFlags & CHN_16BIT) ? RS_PCM16U : RS_PCM8U,
+-								(LPSTR)(lpStream + dwMemPos), dwMemLength - dwMemPos);
+-	}
+-	m_nMinPeriod = 64;
+-	m_nMaxPeriod = 32767;
+-	return TRUE;
+-}
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_okt.cxx audacious-plugins-2.5.4/src/modplug/load_okt.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_okt.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_okt.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,197 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>,
+- *          Adam Goode       <adam at evdebs.org> (endian and char fixes for PPC)
+-*/
+-
+-//////////////////////////////////////////////
+-// Oktalyzer (OKT) module loader            //
+-//////////////////////////////////////////////
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#pragma warning(disable:4244)
+-
+-typedef struct OKTFILEHEADER
+-{
+-	DWORD okta;		// "OKTA"
+-	DWORD song;		// "SONG"
+-	DWORD cmod;		// "CMOD"
+-	DWORD fixed8;
+-	BYTE chnsetup[8];
+-	DWORD samp;		// "SAMP"
+-	DWORD samplen;
+-} OKTFILEHEADER;
+-
+-
+-typedef struct OKTSAMPLE
+-{
+-	CHAR name[20];
+-	DWORD length;
+-	WORD loopstart;
+-	WORD looplen;
+-	BYTE pad1;
+-	BYTE volume;
+-	BYTE pad2;
+-	BYTE pad3;
+-} OKTSAMPLE;
+-
+-
+-BOOL CSoundFile::ReadOKT(const BYTE *lpStream, DWORD dwMemLength)
+-//---------------------------------------------------------------
+-{
+-	OKTFILEHEADER *pfh = (OKTFILEHEADER *)lpStream;
+-	DWORD dwMemPos = sizeof(OKTFILEHEADER);
+-	UINT nsamples = 0, norders = 0;
+-
+-	if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
+-	if ((pfh->okta != 0x41544B4F) || (pfh->song != 0x474E4F53)
+-	 || (pfh->cmod != 0x444F4D43) || (pfh->chnsetup[0]) || (pfh->chnsetup[2])
+-	 || (pfh->chnsetup[4]) || (pfh->chnsetup[6]) || (pfh->fixed8 != 0x08000000)
+-	 || (pfh->samp != 0x504D4153)) return FALSE;
+-	m_nType = MOD_TYPE_OKT;
+-	m_nChannels = 4 + pfh->chnsetup[1] + pfh->chnsetup[3] + pfh->chnsetup[5] + pfh->chnsetup[7];
+-	if (m_nChannels > MAX_CHANNELS) m_nChannels = MAX_CHANNELS;
+-	nsamples = bswapBE32(pfh->samplen) >> 5;
+-	m_nSamples = nsamples;
+-	if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES-1;
+-	// Reading samples
+-	for (UINT smp=1; smp <= nsamples; smp++)
+-	{
+-		if (dwMemPos >= dwMemLength) return TRUE;
+-		if (smp < MAX_SAMPLES)
+-		{
+-			OKTSAMPLE *psmp = (OKTSAMPLE *)(lpStream + dwMemPos);
+-			MODINSTRUMENT *pins = &Ins[smp];
+-
+-			memcpy(m_szNames[smp], psmp->name, 20);
+-			pins->uFlags = 0;
+-			pins->nLength = bswapBE32(psmp->length) & ~1;
+-			pins->nLoopStart = bswapBE16(psmp->loopstart);
+-			pins->nLoopEnd = pins->nLoopStart + bswapBE16(psmp->looplen);
+-			if (pins->nLoopStart + 2 < pins->nLoopEnd) pins->uFlags |= CHN_LOOP;
+-			pins->nGlobalVol = 64;
+-			pins->nVolume = psmp->volume << 2;
+-			pins->nC4Speed = 8363;
+-		}
+-		dwMemPos += sizeof(OKTSAMPLE);
+-	}
+-	// SPEE
+-	if (dwMemPos >= dwMemLength) return TRUE;
+-	if (*((DWORD *)(lpStream + dwMemPos)) == 0x45455053)
+-	{
+-		m_nDefaultSpeed = lpStream[dwMemPos+9];
+-		dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
+-	}
+-	// SLEN
+-	if (dwMemPos >= dwMemLength) return TRUE;
+-	if (*((DWORD *)(lpStream + dwMemPos)) == 0x4E454C53)
+-	{
+-		dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
+-	}
+-	// PLEN
+-	if (dwMemPos >= dwMemLength) return TRUE;
+-	if (*((DWORD *)(lpStream + dwMemPos)) == 0x4E454C50)
+-	{
+-		norders = lpStream[dwMemPos+9];
+-		dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
+-	}
+-	// PATT
+-	if (dwMemPos >= dwMemLength) return TRUE;
+-	if (*((DWORD *)(lpStream + dwMemPos)) == 0x54544150)
+-	{
+-		UINT orderlen = norders;
+-		if (orderlen >= MAX_ORDERS) orderlen = MAX_ORDERS-1;
+-		for (UINT i=0; i<orderlen; i++) Order[i] = lpStream[dwMemPos+10+i];
+-		for (UINT j=orderlen; j>1; j--) { if (Order[j-1]) break; Order[j-1] = 0xFF; }
+-		dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
+-	}
+-	// PBOD
+-	UINT npat = 0;
+-	while ((dwMemPos+10 < dwMemLength) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4250))
+-	{
+-		DWORD dwPos = dwMemPos + 10;
+-		UINT rows = lpStream[dwMemPos+9];
+-		if (!rows) rows = 64;
+-		if (npat < MAX_PATTERNS)
+-		{
+-			if ((Patterns[npat] = AllocatePattern(rows, m_nChannels)) == NULL) return TRUE;
+-			MODCOMMAND *m = Patterns[npat];
+-			PatternSize[npat] = rows;
+-			PatternAllocSize[npat] = rows;
+-			UINT imax = m_nChannels*rows;
+-			for (UINT i=0; i<imax; i++, m++, dwPos+=4)
+-			{
+-				if (dwPos+4 > dwMemLength) break;
+-				const BYTE *p = lpStream+dwPos;
+-				UINT note = p[0];
+-				if (note)
+-				{
+-					m->note = note + 48;
+-					m->instr = p[1] + 1;
+-				}
+-				UINT command = p[2];
+-				UINT param = p[3];
+-				m->param = param;
+-				switch(command)
+-				{
+-				// 0: no effect
+-				case 0:
+-					break;
+-				// 1: Portamento Up
+-				case 1:
+-				case 17:
+-				case 30:
+-					if (param) m->command = CMD_PORTAMENTOUP;
+-					break;
+-				// 2: Portamento Down
+-				case 2:
+-				case 13:
+-				case 21:
+-					if (param) m->command = CMD_PORTAMENTODOWN;
+-					break;
+-				// 10: Arpeggio
+-				case 10:
+-				case 11:
+-				case 12:
+-					m->command = CMD_ARPEGGIO;
+-					break;
+-				// 15: Filter
+-				case 15:
+-					m->command = CMD_MODCMDEX;
+-					m->param = param & 0x0F;
+-					break;
+-				// 25: Position Jump
+-				case 25:
+-					m->command = CMD_POSITIONJUMP;
+-					break;
+-				// 28: Set Speed
+-				case 28:
+-					m->command = CMD_SPEED;
+-					break;
+-				// 31: Volume Control
+-				case 31:
+-					if (param <= 0x40) m->command = CMD_VOLUME; else
+-					if (param <= 0x50) { m->command = CMD_VOLUMESLIDE; m->param &= 0x0F; if (!m->param) m->param = 0x0F; } else
+-					if (param <= 0x60) { m->command = CMD_VOLUMESLIDE; m->param = (param & 0x0F) << 4; if (!m->param) m->param = 0xF0; } else
+-					if (param <= 0x70) { m->command = CMD_MODCMDEX; m->param = 0xB0 | (param & 0x0F); if (!(param & 0x0F)) m->param = 0xBF; } else
+-					if (param <= 0x80) { m->command = CMD_MODCMDEX; m->param = 0xA0 | (param & 0x0F); if (!(param & 0x0F)) m->param = 0xAF; }
+-					break;
+-				}
+-			}
+-		}
+-		npat++;
+-		dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
+-	}
+-	// SBOD
+-	UINT nsmp = 1;
+-	while ((dwMemPos+10 < dwMemLength) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4253))
+-	{
+-		if (nsmp < MAX_SAMPLES) ReadSample(&Ins[nsmp], RS_PCM8S, (LPSTR)(lpStream+dwMemPos+8), dwMemLength-dwMemPos-8);
+-		dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
+-		nsmp++;
+-	}
+-	return TRUE;
+-}
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_psm.cxx audacious-plugins-2.5.4/src/modplug/load_psm.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_psm.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_psm.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,882 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-
+-///////////////////////////////////////////////////
+-//
+-// PSM module loader
+-//
+-///////////////////////////////////////////////////
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#define PSM_LOG
+-
+-#define PSM_ID_NEW	0x204d5350
+-#define PSM_ID_OLD	0xfe4d5350
+-#define IFFID_FILE	0x454c4946
+-#define IFFID_TITL	0x4c544954
+-#define IFFID_SDFT	0x54464453
+-#define IFFID_PBOD	0x444f4250
+-#define IFFID_SONG	0x474e4f53
+-#define IFFID_PATT	0x54544150
+-#define IFFID_DSMP	0x504d5344
+-#define IFFID_OPLH	0x484c504f
+-
+-#pragma pack(1)
+-
+-typedef struct _PSMCHUNK
+-{
+-	DWORD id;
+-	DWORD len;
+-	DWORD listid;
+-} PSMCHUNK;
+-
+-typedef struct _PSMSONGHDR
+-{
+-	CHAR songname[8];	// "MAINSONG"
+-	BYTE reserved1;
+-	BYTE reserved2;
+-	BYTE channels;
+-} PSMSONGHDR;
+-
+-typedef struct _PSMPATTERN
+-{
+-	DWORD size;
+-	DWORD name;
+-	WORD rows;
+-	WORD reserved1;
+-	BYTE data[4];
+-} PSMPATTERN;
+-
+-typedef struct _PSMSAMPLE
+-{
+-	BYTE flags;
+-	CHAR songname[8];
+-	DWORD smpid;
+-	CHAR samplename[34];
+-	DWORD reserved1;
+-	BYTE reserved2;
+-	BYTE insno;
+-	BYTE reserved3;
+-	DWORD length;
+-	DWORD loopstart;
+-	DWORD loopend;
+-	WORD reserved4;
+-	BYTE defvol;
+-	DWORD reserved5;
+-	DWORD samplerate;
+-	BYTE reserved6[19];
+-} PSMSAMPLE;
+-
+-#pragma pack()
+-
+-
+-BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength)
+-//-----------------------------------------------------------
+-{
+-	PSMCHUNK *pfh = (PSMCHUNK *)lpStream;
+-	DWORD dwMemPos, dwSongPos;
+-	DWORD patptrs[MAX_PATTERNS];
+-	BYTE samplemap[MAX_SAMPLES];
+-	UINT nPatterns;
+-
+-	// Chunk0: "PSM ",filesize,"FILE"
+-	if (dwMemLength < 256) return FALSE;
+-	if (bswapLE32(pfh->id) == PSM_ID_OLD)
+-	{
+-	#ifdef PSM_LOG
+-		printf("Old PSM format not supported\n");
+-	#endif
+-		return FALSE;
+-	}
+-	if ((bswapLE32(pfh->id) != PSM_ID_NEW)
+-	|| (bswapLE32(pfh->len)+12 > dwMemLength)
+-	|| (bswapLE32(pfh->listid) != IFFID_FILE)) return FALSE;
+-	m_nType = MOD_TYPE_PSM;
+-	m_nChannels = 16;
+-	m_nSamples = 0;
+-	nPatterns = 0;
+-	dwMemPos = 12;
+-	dwSongPos = 0;
+-	for (UINT iChPan=0; iChPan<16; iChPan++)
+-	{
+-		UINT pan = (((iChPan & 3) == 1) || ((iChPan&3)==2)) ? 0xC0 : 0x40;
+-		ChnSettings[iChPan].nPan = pan;
+-	}
+-	m_szNames[0][0]=0;
+-	while (dwMemPos+8 < dwMemLength)
+-	{
+-		PSMCHUNK *pchunk = (PSMCHUNK *)(lpStream+dwMemPos);
+-		if ((bswapLE32(pchunk->len) >= dwMemLength - 8)
+-		|| (dwMemPos + bswapLE32(pchunk->len) + 8 > dwMemLength)) break;
+-		dwMemPos += 8;
+-		PUCHAR pdata = (PUCHAR)(lpStream+dwMemPos);
+-		ULONG len = bswapLE32(pchunk->len);
+-		if (len) switch(bswapLE32(pchunk->id))
+-		{
+-		// "TITL": Song title
+-		case IFFID_TITL:
+-			if (!pdata[0]) { pdata++; len--; }
+-			memcpy(m_szNames[0], pdata, (len>31) ? 31 : len);
+-			m_szNames[0][31] = 0;
+-			break;
+-		// "PBOD": Pattern
+-		case IFFID_PBOD:
+-			if ((len >= 12) && (nPatterns < MAX_PATTERNS))
+-			{
+-				patptrs[nPatterns++] = dwMemPos-8;
+-			}
+-			break;
+-		// "SONG": Song description
+-		case IFFID_SONG:
+-			if ((len >= sizeof(PSMSONGHDR)+8) && (!dwSongPos))
+-			{
+-				dwSongPos = dwMemPos - 8;
+-			}
+-			break;
+-		// "DSMP": Sample Data
+-		case IFFID_DSMP:
+-			if ((len >= sizeof(PSMSAMPLE)) && (m_nSamples+1 < MAX_SAMPLES))
+-			{
+-				m_nSamples++;
+-				MODINSTRUMENT *pins = &Ins[m_nSamples];
+-				PSMSAMPLE *psmp = (PSMSAMPLE *)pdata;
+-				memcpy(m_szNames[m_nSamples], psmp->samplename, 31);
+-				m_szNames[m_nSamples][31] = 0;
+-				samplemap[m_nSamples-1] = (BYTE)m_nSamples;
+-				// Init sample
+-				pins->nGlobalVol = 0x40;
+-				pins->nC4Speed = bswapLE32(psmp->samplerate);
+-				pins->nLength = bswapLE32(psmp->length);
+-				pins->nLoopStart = bswapLE32(psmp->loopstart);
+-				pins->nLoopEnd = bswapLE32(psmp->loopend);
+-				pins->nPan = 128;
+-				pins->nVolume = (psmp->defvol+1) * 2;
+-				pins->uFlags = (psmp->flags & 0x80) ? CHN_LOOP : 0;
+-				if (pins->nLoopStart > 0) pins->nLoopStart--;
+-				// Point to sample data
+-				pdata += 0x60;
+-				len -= 0x60;
+-				// Load sample data
+-				if ((pins->nLength > 3) && (len > 3))
+-				{
+-					ReadSample(pins, RS_PCM8D, (LPCSTR)pdata, len);
+-				} else
+-				{
+-					pins->nLength = 0;
+-				}
+-			}
+-			break;
+-	#if 0
+-		default:
+-			{
+-				CHAR s[8], s2[64];
+-				*(DWORD *)s = pchunk->id;
+-				s[4] = 0;
+-				wsprintf(s2, "%s: %4d bytes @ %4d\n", s, pchunk->len, dwMemPos);
+-				OutputDebugString(s2);
+-			}
+-	#endif
+-		}
+-		dwMemPos += bswapLE32(pchunk->len);
+-	}
+-	// Step #1: convert song structure
+-	PSMSONGHDR *pSong = (PSMSONGHDR *)(lpStream+dwSongPos+8);
+-	if ((!dwSongPos) || (pSong->channels < 2) || (pSong->channels > 32)) return TRUE;
+-	m_nChannels = pSong->channels;
+-	// Valid song header -> convert attached chunks
+-	{
+-		DWORD dwSongEnd = dwSongPos + 8 + *(DWORD *)(lpStream+dwSongPos+4);
+-		dwMemPos = dwSongPos + 8 + 11; // sizeof(PSMCHUNK)+sizeof(PSMSONGHDR)
+-		while (dwMemPos + 8 < dwSongEnd)
+-		{
+-			PSMCHUNK *pchunk = (PSMCHUNK *)(lpStream+dwMemPos);
+-			dwMemPos += 8;
+-			if ((bswapLE32(pchunk->len) > dwSongEnd)
+-			|| (dwMemPos + bswapLE32(pchunk->len) > dwSongEnd)) break;
+-			PUCHAR pdata = (PUCHAR)(lpStream+dwMemPos);
+-			ULONG len = bswapLE32(pchunk->len);
+-			switch(bswapLE32(pchunk->id))
+-			{
+-			case IFFID_OPLH:
+-				if (len >= 0x20)
+-				{
+-					UINT pos = len - 3;
+-					while (pos > 5)
+-					{
+-						BOOL bFound = FALSE;
+-						pos -= 5;
+-						DWORD dwName = *(DWORD *)(pdata+pos);
+-						for (UINT i=0; i<nPatterns; i++)
+-						{
+-							DWORD dwPatName = ((PSMPATTERN *)(lpStream+patptrs[i]+8))->name;
+-							if (dwName == dwPatName)
+-							{
+-								bFound = TRUE;
+-								break;
+-							}
+-						}
+-						if ((!bFound) && (pdata[pos+1] > 0) && (pdata[pos+1] <= 0x10)
+-						 && (pdata[pos+3] > 0x40) && (pdata[pos+3] < 0xC0))
+-						{
+-							m_nDefaultSpeed = pdata[pos+1];
+-							m_nDefaultTempo = pdata[pos+3];
+-							break;
+-						}
+-					}
+-					UINT iOrd = 0;
+-					while ((pos+5<len) && (iOrd < MAX_ORDERS))
+-					{
+-						DWORD dwName = *(DWORD *)(pdata+pos);
+-						for (UINT i=0; i<nPatterns; i++)
+-						{
+-							DWORD dwPatName = ((PSMPATTERN *)(lpStream+patptrs[i]+8))->name;
+-							if (dwName == dwPatName)
+-							{
+-								Order[iOrd++] = i;
+-								break;
+-							}
+-						}
+-						pos += 5;
+-					}
+-				}
+-				break;
+-			}
+-			dwMemPos += bswapLE32(pchunk->len);
+-		}
+-	}
+-
+-	// Step #2: convert patterns
+-	for (UINT nPat=0; nPat<nPatterns; nPat++)
+-	{
+-		PSMPATTERN *pPsmPat = (PSMPATTERN *)(lpStream+patptrs[nPat]+8);
+-		ULONG len = bswapLE32(*(DWORD *)(lpStream+patptrs[nPat]+4)) - 12;
+-		UINT nRows = bswapLE16(pPsmPat->rows);
+-		if (len > bswapLE32(pPsmPat->size)) len = bswapLE32(pPsmPat->size);
+-		if ((nRows < 64) || (nRows > 256)) nRows = 64;
+-		PatternSize[nPat] = nRows;
+-		PatternAllocSize[nPat] = nRows;
+-		if ((Patterns[nPat] = AllocatePattern(nRows, m_nChannels)) == NULL) break;
+-		MODCOMMAND *m = Patterns[nPat];
+-		MODCOMMAND *sp, dummy;
+-		BYTE *p = pPsmPat->data;
+-		UINT pos = 0;
+-		UINT row = 0;
+-		UINT rowlim;
+-	#ifdef PSM_LOG
+-		//printf("Pattern %d at offset 0x%04X\n", nPat, (DWORD)(p - (BYTE *)lpStream));
+-	#endif
+-		rowlim = bswapLE16(pPsmPat->reserved1)-2;
+-		while ((row < nRows) && (pos+1 < len))
+-		{
+-			UINT flags, ch;
+-			if ((pos+1) >= rowlim) {
+-				pos = rowlim;
+-				rowlim = (((int)p[pos+1])<<8)
+-					| ((int)p[pos+0]);
+-				m += m_nChannels;
+-				row++;
+-				rowlim += pos;
+-				pos += 2;
+-			}
+-			flags = p[pos++];
+-			ch = p[pos++];
+-			if (ch >= m_nChannels) {
+-			#ifdef PSM_LOG
+-				printf("Invalid channel row=%d (0x%02X.0x%02X)\n", row, flags, ch);
+-			#endif
+-				sp = &dummy;
+-			} else {
+-				sp = &m[ch];
+-			}
+-			// Note + Instr
+-			if ((flags & 0x80) && (pos+1 < len))
+-			{
+-				UINT note = p[pos++];
+-				note = (note>>4)*12+(note&0x0f)+12+1;
+-				if (note > 0x80) note = 0;
+-				sp->note = note;
+-			}
+-			if ((flags & 0x40) && (pos+1 < len))
+-			{
+-				UINT nins = p[pos++];
+-			#ifdef PSM_LOG
+-				if ((!nPat) && (nins >= m_nSamples)) printf("WARNING: invalid instrument number (%d)\n", nins);
+-			#endif
+-				sp->instr = samplemap[nins];
+-			}
+-			// Volume
+-			if ((flags & 0x20) && (pos < len))
+-			{
+-				sp->volcmd = VOLCMD_VOLUME;
+-				sp->vol = p[pos++] / 2;
+-			}
+-			// Effect
+-			if ((flags & 0x10) && (pos+1 < len))
+-			{
+-				UINT command = p[pos++];
+-				UINT param = p[pos++];
+-				// Convert effects
+-				switch(command & 0x3F)
+-				{
+-				// 01: fine volslide up
+-				case 0x01:
+-#if PSM_LOG
+-					printf("fvup command pat=%d row=%d ch=%d   %02x %02x\n",
+-							nPat,
+-								row,1+ch,
+-								command, param);
+-#endif
+-#if 0
+-					if (!sp->volcmd) {
+-						sp->volcmd = VOLCMD_FINEVOLUP;
+-						sp->vol = (param >> 1) & 0xF;
+-						command = CMD_PORTAMENTOUP;
+-						param>>=4; param |= 0xf0;
+-						if (param == 240) param=241;
+-					} else {
+-#endif
+-					command = CMD_VOLUMESLIDE;
+-					param |= 0x0f;
+-					if (param == 15) param=31;
+-					break;
+-				// 02: volslide up
+-				case 0x02:	command = CMD_VOLUMESLIDE; param>>=1; param<<=4; break;
+-				// 03: fine volslide down
+-				case 0x03:	
+-#if PSM_LOG
+-					printf("fvdown command pat=%d row=%d ch=%d   %02x %02x\n",
+-							nPat,
+-								row,1+ch,
+-								command, param);
+-#endif
+-#if 0
+-					if (!sp->volcmd) {
+-						sp->volcmd = VOLCMD_FINEVOLDOWN;
+-						sp->vol = (param >> 2) & 0xF;
+-						if (!sp->vol) sp->vol = 1;
+-						command = CMD_PORTAMENTODOWN;
+-					}
+-#endif
+-					command = CMD_VOLUMESLIDE;
+-					param>>=4; param |= 0xf0;
+-					if (param == 240) param=241;
+-					break;
+-				// 04: volslide down
+-				case 0x04:	command = CMD_VOLUMESLIDE; param>>=1; break;
+-				// 0C: portamento up
+-				case 0x0C:	command = CMD_PORTAMENTOUP; param = (param+1)/2; break;
+-				// 0E: portamento down
+-				case 0x0E:	command = CMD_PORTAMENTODOWN; param = (param+1)/2; break;
+-				// 0F: tone portamento
+-				case 0x0F:	command = CMD_TONEPORTAMENTO; param = param/4; break;
+-				// 15: vibrato
+-				case 0x15:	command = CMD_VIBRATO; break;
+-				// 29: wtf
+-				case 0x29: pos += 2; break;
+-				// 2A: retrig
+-				case 0x2A:	command = CMD_RETRIG; break;
+-				// 33: Position Jump
+-				case 0x33:	command = CMD_POSITIONJUMP; break;
+-				// 34: Pattern break
+-				case 0x34:	command = CMD_PATTERNBREAK; break;
+-				// 3D: speed
+-				case 0x3D:	command = CMD_SPEED;
+-						if (!row && !nPat)
+-							m_nDefaultSpeed = param;
+-						break;
+-				// 3E: tempo
+-				case 0x3E:	command = CMD_TEMPO;
+-						if (!row && !nPat)
+-							m_nDefaultTempo = param;
+-						break;
+-				// Unknown
+-				default:
+-				#ifdef PSM_LOG
+-					printf("Unknown PSM effect pat=%d row=%d ch=%d: %02X.%02X\n", nPat, row, ch, command, param);
+-				#endif
+-					command = param = 0;
+-				}
+-				sp->command = (BYTE)command;
+-				sp->param = (BYTE)param;
+-			}
+-		}
+-	#ifdef PSM_LOG
+-		if (pos < len)
+-		{
+-//			printf("Pattern %d: %d/%d[%d] rows (%d bytes) -> %d bytes left\n", nPat, row, nRows, pPsmPat->rows, pPsmPat->size, len-pos);
+-		}
+-	#endif
+-	}
+-
+-	// Done (finally!)
+-	return TRUE;
+-}
+-
+-
+-//////////////////////////////////////////////////////////////
+-//
+-// PSM Old Format
+-//
+-
+-/*
+-
+-CONST
+-  c_PSM_MaxOrder   = $FF;
+-  c_PSM_MaxSample  = $FF;
+-  c_PSM_MaxChannel = $0F;
+-
+- TYPE
+-  PPSM_Header = ^TPSM_Header;
+-  TPSM_Header = RECORD
+-                 PSM_Sign                   : ARRAY[01..04] OF CHAR; { PSM + #254 }
+-                 PSM_SongName               : ARRAY[01..58] OF CHAR;
+-                 PSM_Byte00                 : BYTE;
+-                 PSM_Byte1A                 : BYTE;
+-                 PSM_Unknown00              : BYTE;
+-                 PSM_Unknown01              : BYTE;
+-                 PSM_Unknown02              : BYTE;
+-                 PSM_Speed                  : BYTE;
+-                 PSM_Tempo                  : BYTE;
+-                 PSM_Unknown03              : BYTE;
+-                 PSM_Unknown04              : WORD;
+-                 PSM_OrderLength            : WORD;
+-                 PSM_PatternNumber          : WORD;
+-                 PSM_SampleNumber           : WORD;
+-                 PSM_ChannelNumber          : WORD;
+-                 PSM_ChannelUsed            : WORD;
+-                 PSM_OrderPosition          : LONGINT;
+-                 PSM_ChannelSettingPosition : LONGINT;
+-                 PSM_PatternPosition        : LONGINT;
+-                 PSM_SamplePosition         : LONGINT;
+-                { *** perhaps there are some more infos in a larger header,
+-                      but i have not decoded it and so it apears here NOT }
+-                END;
+-
+-  PPSM_Sample = ^TPSM_Sample;
+-  TPSM_Sample = RECORD
+-                 PSM_SampleFileName  : ARRAY[01..12] OF CHAR;
+-                 PSM_SampleByte00    : BYTE;
+-                 PSM_SampleName      : ARRAY[01..22] OF CHAR;
+-                 PSM_SampleUnknown00 : ARRAY[01..02] OF BYTE;
+-                 PSM_SamplePosition  : LONGINT;
+-                 PSM_SampleUnknown01 : ARRAY[01..04] OF BYTE;
+-                 PSM_SampleNumber    : BYTE;
+-                 PSM_SampleFlags     : WORD;
+-                 PSM_SampleLength    : LONGINT;
+-                 PSM_SampleLoopBegin : LONGINT;
+-                 PSM_SampleLoopEnd   : LONGINT;
+-                 PSM_Unknown03       : BYTE;
+-                 PSM_SampleVolume    : BYTE;
+-                 PSM_SampleC5Speed   : WORD;
+-                END;
+-
+-  PPSM_SampleList = ^TPSM_SampleList;
+-  TPSM_SampleList = ARRAY[01..c_PSM_MaxSample] OF TPSM_Sample;
+-
+-  PPSM_Order = ^TPSM_Order;
+-  TPSM_Order = ARRAY[00..c_PSM_MaxOrder] OF BYTE;
+-
+-  PPSM_ChannelSettings = ^TPSM_ChannelSettings;
+-  TPSM_ChannelSettings = ARRAY[00..c_PSM_MaxChannel] OF BYTE;
+-
+- CONST
+-  PSM_NotesInPattern   : BYTE = $00;
+-  PSM_ChannelInPattern : BYTE = $00;
+-
+- CONST
+-  c_PSM_SetSpeed = 60;
+-
+- FUNCTION PSM_Size(FileName : STRING;FilePosition : LONGINT) : LONGINT;
+-  BEGIN
+-  END;
+-
+- PROCEDURE PSM_UnpackPattern(VAR Source,Destination;PatternLength : WORD);
+-  VAR
+-   Witz : ARRAY[00..04] OF WORD;
+-   I1,I2        : WORD;
+-   I3,I4        : WORD;
+-   TopicalByte  : ^BYTE;
+-   Pattern      : PUnpackedPattern;
+-   ChannelP     : BYTE;
+-   NoteP        : BYTE;
+-   InfoByte     : BYTE;
+-   CodeByte     : BYTE;
+-   InfoWord     : WORD;
+-   Effect       : BYTE;
+-   Opperand     : BYTE;
+-   Panning      : BYTE;
+-   Volume       : BYTE;
+-   PrevInfo     : BYTE;
+-   InfoIndex    : BYTE;
+-  BEGIN
+-   Pattern     := @Destination;
+-   TopicalByte := @Source;
+-  { *** Initialize patttern }
+-   FOR I2 := 0 TO c_Maximum_NoteIndex DO
+-    FOR I3 := 0 TO c_Maximum_ChannelIndex DO
+-     BEGIN
+-      Pattern^[I2,I3,c_Pattern_NoteIndex]     := $FF;
+-      Pattern^[I2,I3,c_Pattern_SampleIndex]   := $00;
+-      Pattern^[I2,I3,c_Pattern_VolumeIndex]   := $FF;
+-      Pattern^[I2,I3,c_Pattern_PanningIndex]  := $FF;
+-      Pattern^[I2,I3,c_Pattern_EffectIndex]   := $00;
+-      Pattern^[I2,I3,c_Pattern_OpperandIndex] := $00;
+-     END;
+-  { *** Byte-pointer on first pattern-entry }
+-   ChannelP    := $00;
+-   NoteP       := $00;
+-   InfoByte    := $00;
+-   PrevInfo    := $00;
+-   InfoIndex   := $02;
+-  { *** read notes in pattern }
+-   PSM_NotesInPattern   := TopicalByte^; INC(TopicalByte); DEC(PatternLength); INC(InfoIndex);
+-   PSM_ChannelInPattern := TopicalByte^; INC(TopicalByte); DEC(PatternLength); INC(InfoIndex);
+-  { *** unpack pattern }
+-   WHILE (INTEGER(PatternLength) > 0) AND (NoteP < c_Maximum_NoteIndex) DO
+-    BEGIN
+-    { *** Read info-byte }
+-     InfoByte := TopicalByte^; INC(TopicalByte); DEC(PatternLength); INC(InfoIndex);
+-     IF InfoByte <> $00 THEN
+-      BEGIN
+-       ChannelP := InfoByte AND $0F;
+-       IF InfoByte AND 128 = 128 THEN { note and sample }
+-        BEGIN
+-        { *** read note }
+-         CodeByte := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
+-         DEC(CodeByte);
+-         CodeByte := CodeByte MOD 12 * 16 + CodeByte DIV 12 + 2;
+-         Pattern^[NoteP,ChannelP,c_Pattern_NoteIndex] := CodeByte;
+-        { *** read sample }
+-         CodeByte := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
+-         Pattern^[NoteP,ChannelP,c_Pattern_SampleIndex] := CodeByte;
+-        END;
+-       IF InfoByte AND 64 = 64 THEN { Volume }
+-        BEGIN
+-         CodeByte := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
+-         Pattern^[NoteP,ChannelP,c_Pattern_VolumeIndex] := CodeByte;
+-        END;
+-       IF InfoByte AND 32 = 32 THEN { effect AND opperand }
+-        BEGIN
+-         Effect   := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
+-         Opperand := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
+-         CASE Effect OF
+-          c_PSM_SetSpeed:
+-           BEGIN
+-            Effect := c_I_Set_Speed;
+-           END;
+-          ELSE
+-           BEGIN
+-            Effect   := c_I_NoEffect;
+-            Opperand := $00;
+-           END;
+-         END;
+-         Pattern^[NoteP,ChannelP,c_Pattern_EffectIndex]   := Effect;
+-         Pattern^[NoteP,ChannelP,c_Pattern_OpperandIndex] := Opperand;
+-        END;
+-      END ELSE INC(NoteP);
+-    END;
+-  END;
+-
+- PROCEDURE PSM_Load(FileName : STRING;FilePosition : LONGINT;VAR Module : PModule;VAR ErrorCode : WORD);
+- { *** caution : Module has to be inited before!!!! }
+-  VAR
+-   Header             : PPSM_Header;
+-   Sample             : PPSM_SampleList;
+-   Order              : PPSM_Order;
+-   ChannelSettings    : PPSM_ChannelSettings;
+-   MultiPurposeBuffer : PByteArray;
+-   PatternBuffer      : PUnpackedPattern;
+-   TopicalParaPointer : WORD;
+-
+-   InFile : FILE;
+-   I1,I2  : WORD;
+-   I3,I4  : WORD;
+-   TempW  : WORD;
+-   TempB  : BYTE;
+-   TempP  : PByteArray;
+-   TempI  : INTEGER;
+-  { *** copy-vars for loop-extension }
+-   CopySource      : LONGINT;
+-   CopyDestination : LONGINT;
+-   CopyLength      : LONGINT;
+-  BEGIN
+-  { *** try to open file }
+-   ASSIGN(InFile,FileName);
+-{$I-}
+-   RESET(InFile,1);
+-{$I+}
+-   IF IORESULT <> $00 THEN
+-    BEGIN
+-     EXIT;
+-    END;
+-{$I-}
+-  { *** seek start of module }
+-   IF FILESIZE(InFile) < FilePosition THEN
+-    BEGIN
+-     EXIT;
+-    END;
+-   SEEK(InFile,FilePosition);
+-  { *** look for enough memory for temporary variables }
+-   IF MEMAVAIL < SIZEOF(TPSM_Header)       + SIZEOF(TPSM_SampleList) +
+-                 SIZEOF(TPSM_Order)        + SIZEOF(TPSM_ChannelSettings) +
+-                 SIZEOF(TByteArray)        + SIZEOF(TUnpackedPattern)
+-   THEN
+-    BEGIN
+-     EXIT;
+-    END;
+-  { *** init dynamic variables }
+-   NEW(Header);
+-   NEW(Sample);
+-   NEW(Order);
+-   NEW(ChannelSettings);
+-   NEW(MultiPurposeBuffer);
+-   NEW(PatternBuffer);
+-  { *** read header }
+-   BLOCKREAD(InFile,Header^,SIZEOF(TPSM_Header));
+-  { *** test if this is a DSM-file }
+-   IF NOT ((Header^.PSM_Sign[1] = 'P') AND (Header^.PSM_Sign[2] = 'S')   AND
+-           (Header^.PSM_Sign[3] = 'M') AND (Header^.PSM_Sign[4] = #254)) THEN
+-    BEGIN
+-     ErrorCode := c_NoValidFileFormat;
+-     CLOSE(InFile);
+-     EXIT;
+-    END;
+-  { *** read order }
+-   SEEK(InFile,FilePosition + Header^.PSM_OrderPosition);
+-   BLOCKREAD(InFile,Order^,Header^.PSM_OrderLength);
+-  { *** read channelsettings }
+-   SEEK(InFile,FilePosition + Header^.PSM_ChannelSettingPosition);
+-   BLOCKREAD(InFile,ChannelSettings^,SIZEOF(TPSM_ChannelSettings));
+-  { *** read samplelist }
+-   SEEK(InFile,FilePosition + Header^.PSM_SamplePosition);
+-   BLOCKREAD(InFile,Sample^,Header^.PSM_SampleNumber * SIZEOF(TPSM_Sample));
+-  { *** copy header to intern NTMIK-structure }
+-   Module^.Module_Sign                 := 'MF';
+-   Module^.Module_FileFormatVersion    := $0100;
+-   Module^.Module_SampleNumber         := Header^.PSM_SampleNumber;
+-   Module^.Module_PatternNumber        := Header^.PSM_PatternNumber;
+-   Module^.Module_OrderLength          := Header^.PSM_OrderLength;
+-   Module^.Module_ChannelNumber        := Header^.PSM_ChannelNumber+1;
+-   Module^.Module_Initial_GlobalVolume := 64;
+-   Module^.Module_Initial_MasterVolume := $C0;
+-   Module^.Module_Initial_Speed        := Header^.PSM_Speed;
+-   Module^.Module_Initial_Tempo        := Header^.PSM_Tempo;
+-{ *** paragraph 01 start }
+-   Module^.Module_Flags                := c_Module_Flags_ZeroVolume        * BYTE(1) +
+-                                          c_Module_Flags_Stereo            * BYTE(1) +
+-                                          c_Module_Flags_ForceAmigaLimits  * BYTE(0) +
+-                                          c_Module_Flags_Panning           * BYTE(1) +
+-                                          c_Module_Flags_Surround          * BYTE(1) +
+-                                          c_Module_Flags_QualityMixing     * BYTE(1) +
+-                                          c_Module_Flags_FastVolumeSlides  * BYTE(0) +
+-                                          c_Module_Flags_SpecialCustomData * BYTE(0) +
+-                                          c_Module_Flags_SongName          * BYTE(1);
+-   I1 := $01;
+-   WHILE (Header^.PSM_SongName[I1] > #00) AND (I1 < c_Module_SongNameLength) DO
+-    BEGIN
+-     Module^.Module_Name[I1] := Header^.PSM_SongName[I1];
+-     INC(I1);
+-    END;
+-   Module^.Module_Name[c_Module_SongNameLength] := #00;
+-  { *** Init channelsettings }
+-   FOR I1 := 0 TO c_Maximum_ChannelIndex DO
+-    BEGIN
+-     IF I1 < Header^.PSM_ChannelUsed THEN
+-      BEGIN
+-      { *** channel enabled }
+-       Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_GlobalVolume := 64;
+-       Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Panning      := (ChannelSettings^[I1]) * $08;
+-       Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Code         := I1 + $10 * BYTE(ChannelSettings^[I1] > $08) +
+-                                             c_ChannelSettings_Code_ChannelEnabled   * BYTE(1) +
+-                                             c_ChannelSettings_Code_ChannelDigital   * BYTE(1);
+-       Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Controls     :=
+-                                             c_ChannelSettings_Controls_EnhancedMode * BYTE(1) +
+-                                             c_ChannelSettings_Controls_SurroundMode * BYTE(0);
+-      END
+-     ELSE
+-      BEGIN
+-      { *** channel disabled }
+-       Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_GlobalVolume := $00;
+-       Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Panning      := $00;
+-       Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Code         := $00;
+-       Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Controls     := $00;
+-      END;
+-    END;
+-  { *** init and copy order }
+-   FILLCHAR(Module^.Module_OrderPointer^,c_Maximum_OrderIndex+1,$FF);
+-   MOVE(Order^,Module^.Module_OrderPointer^,Header^.PSM_OrderLength);
+-  { *** read pattern }
+-   SEEK(InFile,FilePosition + Header^.PSM_PatternPosition);
+-   NTMIK_LoaderPatternNumber := Header^.PSM_PatternNumber-1;
+-   FOR I1 := 0 TO Header^.PSM_PatternNumber-1 DO
+-    BEGIN
+-     NTMIK_LoadPatternProcedure;
+-    { *** read length }
+-     BLOCKREAD(InFile,TempW,2);
+-    { *** read pattern }
+-     BLOCKREAD(InFile,MultiPurposeBuffer^,TempW-2);
+-    { *** unpack pattern and set notes per channel to 64 }
+-     PSM_UnpackPattern(MultiPurposeBuffer^,PatternBuffer^,TempW);
+-     NTMIK_PackPattern(MultiPurposeBuffer^,PatternBuffer^,PSM_NotesInPattern);
+-     TempW := WORD(256) * MultiPurposeBuffer^[01] + MultiPurposeBuffer^[00];
+-     GETMEM(Module^.Module_PatternPointer^[I1],TempW);
+-     MOVE(MultiPurposeBuffer^,Module^.Module_PatternPointer^[I1]^,TempW);
+-    { *** next pattern }
+-    END;
+-  { *** read samples }
+-   NTMIK_LoaderSampleNumber := Header^.PSM_SampleNumber;
+-   FOR I1 := 1 TO Header^.PSM_SampleNumber DO
+-    BEGIN
+-     NTMIK_LoadSampleProcedure;
+-    { *** get index for sample }
+-     I3 := Sample^[I1].PSM_SampleNumber;
+-    { *** clip PSM-sample }
+-     IF Sample^[I1].PSM_SampleLoopEnd > Sample^[I1].PSM_SampleLength
+-     THEN Sample^[I1].PSM_SampleLoopEnd := Sample^[I1].PSM_SampleLength;
+-    { *** init intern sample }
+-     NEW(Module^.Module_SamplePointer^[I3]);
+-     FILLCHAR(Module^.Module_SamplePointer^[I3]^,SIZEOF(TSample),$00);
+-     FILLCHAR(Module^.Module_SamplePointer^[I3]^.Sample_SampleName,c_Sample_SampleNameLength,#32);
+-     FILLCHAR(Module^.Module_SamplePointer^[I3]^.Sample_FileName,c_Sample_FileNameLength,#32);
+-    { *** copy informations to intern sample }
+-     I2 := $01;
+-     WHILE (Sample^[I1].PSM_SampleName[I2] > #00) AND (I2 < c_Sample_SampleNameLength) DO
+-      BEGIN
+-       Module^.Module_SamplePointer^[I3]^.Sample_SampleName[I2] := Sample^[I1].PSM_SampleName[I2];
+-       INC(I2);
+-      END;
+-     Module^.Module_SamplePointer^[I3]^.Sample_Sign              := 'DF';
+-     Module^.Module_SamplePointer^[I3]^.Sample_FileFormatVersion := $00100;
+-     Module^.Module_SamplePointer^[I3]^.Sample_Position          := $00000000;
+-     Module^.Module_SamplePointer^[I3]^.Sample_Selector          := $0000;
+-     Module^.Module_SamplePointer^[I3]^.Sample_Volume            := Sample^[I1].PSM_SampleVolume;
+-     Module^.Module_SamplePointer^[I3]^.Sample_LoopCounter       := $00;
+-     Module^.Module_SamplePointer^[I3]^.Sample_C5Speed           := Sample^[I1].PSM_SampleC5Speed;
+-     Module^.Module_SamplePointer^[I3]^.Sample_Length            := Sample^[I1].PSM_SampleLength;
+-     Module^.Module_SamplePointer^[I3]^.Sample_LoopBegin         := Sample^[I1].PSM_SampleLoopBegin;
+-     Module^.Module_SamplePointer^[I3]^.Sample_LoopEnd           := Sample^[I1].PSM_SampleLoopEnd;
+-    { *** now it's time for the flags }
+-     Module^.Module_SamplePointer^[I3]^.Sample_Flags :=
+-                                 c_Sample_Flags_DigitalSample      * BYTE(1) +
+-                                 c_Sample_Flags_8BitSample         * BYTE(1) +
+-                                 c_Sample_Flags_UnsignedSampleData * BYTE(1) +
+-                                 c_Sample_Flags_Packed             * BYTE(0) +
+-                                 c_Sample_Flags_LoopCounter        * BYTE(0) +
+-                                 c_Sample_Flags_SampleName         * BYTE(1) +
+-                                 c_Sample_Flags_LoopActive         *
+-                             BYTE(Sample^[I1].PSM_SampleFlags AND (LONGINT(1) SHL 15) = (LONGINT(1) SHL 15));
+-    { *** alloc memory for sample-data }
+-     E_Getmem(Module^.Module_SamplePointer^[I3]^.Sample_Selector,
+-              Module^.Module_SamplePointer^[I3]^.Sample_Position,
+-              Module^.Module_SamplePointer^[I3]^.Sample_Length + c_LoopExtensionSize);
+-    { *** read out data }
+-     EPT(TempP).p_Selector := Module^.Module_SamplePointer^[I3]^.Sample_Selector;
+-     EPT(TempP).p_Offset   := $0000;
+-     SEEK(InFile,Sample^[I1].PSM_SamplePosition);
+-     E_BLOCKREAD(InFile,TempP^,Module^.Module_SamplePointer^[I3]^.Sample_Length);
+-    { *** 'coz the samples are signed in a DSM-file -> PC-fy them }
+-     IF Module^.Module_SamplePointer^[I3]^.Sample_Length > 4 THEN
+-      BEGIN
+-       CopyLength := Module^.Module_SamplePointer^[I3]^.Sample_Length;
+-      { *** decode sample }
+-       ASM
+-        DB 066h; MOV CX,WORD PTR CopyLength
+-       { *** load sample selector }
+-                 MOV ES,WORD PTR TempP[00002h]
+-        DB 066h; XOR SI,SI
+-        DB 066h; XOR DI,DI
+-                 XOR AH,AH
+-       { *** conert all bytes }
+-                @@MainLoop:
+-        DB 026h; DB 067h; LODSB
+-                 ADD AL,AH
+-                 MOV AH,AL
+-        DB 067h; STOSB
+-        DB 066h; LOOP @@MainLoop
+-       END;
+-      { *** make samples unsigned }
+-       ASM
+-        DB 066h; MOV CX,WORD PTR CopyLength
+-       { *** load sample selector }
+-                 MOV ES,WORD PTR TempP[00002h]
+-        DB 066h; XOR SI,SI
+-        DB 066h; XOR DI,DI
+-       { *** conert all bytes }
+-                @@MainLoop:
+-        DB 026h; DB 067h; LODSB
+-                 SUB AL,080h
+-        DB 067h; STOSB
+-        DB 066h; LOOP @@MainLoop
+-       END;
+-      { *** Create Loop-Extension }
+-       IF Module^.Module_SamplePointer^[I3]^.Sample_Flags AND c_Sample_Flags_LoopActive = c_Sample_Flags_LoopActive THEN
+-        BEGIN
+-         CopySource      := Module^.Module_SamplePointer^[I3]^.Sample_LoopBegin;
+-         CopyDestination := Module^.Module_SamplePointer^[I3]^.Sample_LoopEnd;
+-         CopyLength      := CopyDestination - CopySource;
+-         ASM
+-         { *** load sample-selector }
+-                   MOV ES,WORD PTR TempP[00002h]
+-          DB 066h; MOV DI,WORD PTR CopyDestination
+-         { *** calculate number of full sample-loops to copy }
+-                   XOR DX,DX
+-                   MOV AX,c_LoopExtensionSize
+-                   MOV BX,WORD PTR CopyLength
+-                   DIV BX
+-                   OR AX,AX
+-                   JE @@NoFullLoop
+-         { *** copy some full-loops (size=bx) }
+-                   MOV CX,AX
+-                  @@InnerLoop:
+-                   PUSH CX
+-          DB 066h; MOV SI,WORD PTR CopySource
+-                   MOV CX,BX
+-          DB 0F3h; DB 026h,067h,0A4h { REP MOVS BYTE PTR ES:[EDI],ES:[ESI] }
+-                   POP CX
+-                   LOOP @@InnerLoop
+-                  @@NoFullLoop:
+-         { *** calculate number of rest-bytes to copy }
+-          DB 066h; MOV SI,WORD PTR CopySource
+-                   MOV CX,DX
+-          DB 0F3h; DB 026h,067h,0A4h { REP MOVS BYTE PTR ES:[EDI],ES:[ESI] }
+-         END;
+-        END
+-       ELSE
+-        BEGIN
+-         CopyDestination := Module^.Module_SamplePointer^[I3]^.Sample_Length;
+-         ASM
+-         { *** load sample-selector }
+-                   MOV ES,WORD PTR TempP[00002h]
+-          DB 066h; MOV DI,WORD PTR CopyDestination
+-         { *** clear extension }
+-                   MOV CX,c_LoopExtensionSize
+-                   MOV AL,080h
+-          DB 0F3h; DB 067h,0AAh       { REP STOS BYTE PTR ES:[EDI] }
+-         END;
+-        END;
+-      END;
+-    { *** next sample }
+-    END;
+-  { *** init period-ranges }
+-   NTMIK_MaximumPeriod := $0000D600 SHR 1;
+-   NTMIK_MinimumPeriod := $0000D600 SHR 8;
+-  { *** close file }
+-   CLOSE(InFile);
+-  { *** dispose all dynamic variables }
+-   DISPOSE(Header);
+-   DISPOSE(Sample);
+-   DISPOSE(Order);
+-   DISPOSE(ChannelSettings);
+-   DISPOSE(MultiPurposeBuffer);
+-   DISPOSE(PatternBuffer);
+-  { *** set errorcode to noerror }
+-   ErrorCode := c_NoError;
+-  END;
+-
+-*/
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_ptm.cxx audacious-plugins-2.5.4/src/modplug/load_ptm.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_ptm.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_ptm.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,208 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>,
+- *          Adam Goode       <adam at evdebs.org> (endian and char fixes for PPC)
+-*/
+-
+-//////////////////////////////////////////////
+-// PTM PolyTracker module loader            //
+-//////////////////////////////////////////////
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#pragma warning(disable:4244)
+-
+-#pragma pack(1)
+-
+-typedef struct PTMFILEHEADER
+-{
+-	CHAR songname[28];		// name of song, asciiz string
+-	CHAR eof;				// 26
+-	BYTE version_lo;		// 03 version of file, currently 0203h
+-	BYTE version_hi;		// 02
+-	BYTE reserved1;			// reserved, set to 0
+-	WORD norders;			// number of orders (0..256)
+-	WORD nsamples;			// number of instruments (1..255)
+-	WORD npatterns;			// number of patterns (1..128)
+-	WORD nchannels;			// number of channels (voices) used (1..32)
+-	WORD fileflags;			// set to 0
+-	WORD reserved2;			// reserved, set to 0
+-	DWORD ptmf_id;			// song identification, 'PTMF' or 0x464d5450
+-	BYTE reserved3[16];		// reserved, set to 0
+-	BYTE chnpan[32];		// channel panning settings, 0..15, 0 = left, 7 = middle, 15 = right
+-	BYTE orders[256];		// order list, valid entries 0..nOrders-1
+-	WORD patseg[128];		// pattern offsets (*16)
+-} PTMFILEHEADER, *LPPTMFILEHEADER;
+-
+-#define SIZEOF_PTMFILEHEADER	608
+-
+-
+-typedef struct PTMSAMPLE
+-{
+-	BYTE sampletype;		// sample type (bit array)
+-	CHAR filename[12];		// name of external sample file
+-	BYTE volume;			// default volume
+-	WORD nC4Spd;			// C4 speed
+-	WORD sampleseg;			// sample segment (used internally)
+-	WORD fileofs[2];		// offset of sample data
+-	WORD length[2];			// sample size (in bytes)
+-	WORD loopbeg[2];		// start of loop
+-	WORD loopend[2];		// end of loop
+-	WORD gusdata[8];
+-	char  samplename[28];	// name of sample, asciiz  // changed from CHAR
+-	DWORD ptms_id;			// sample identification, 'PTMS' or 0x534d5450
+-} PTMSAMPLE;
+-
+-#define SIZEOF_PTMSAMPLE	80
+-
+-#pragma pack()
+-
+-
+-BOOL CSoundFile::ReadPTM(const BYTE *lpStream, DWORD dwMemLength)
+-//---------------------------------------------------------------
+-{
+-	PTMFILEHEADER pfh = *(LPPTMFILEHEADER)lpStream;
+-	DWORD dwMemPos;
+-	UINT nOrders;
+-
+-	pfh.norders = bswapLE16(pfh.norders);
+-	pfh.nsamples = bswapLE16(pfh.nsamples);
+-	pfh.npatterns = bswapLE16(pfh.npatterns);
+-	pfh.nchannels = bswapLE16(pfh.nchannels);
+-	pfh.fileflags = bswapLE16(pfh.fileflags);
+-	pfh.reserved2 = bswapLE16(pfh.reserved2);
+-	pfh.ptmf_id = bswapLE32(pfh.ptmf_id);
+-	for (UINT j=0; j<128; j++)
+-        {
+-	        pfh.patseg[j] = bswapLE16(pfh.patseg[j]);
+-	}
+-
+-	if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
+-	if ((pfh.ptmf_id != 0x464d5450) || (!pfh.nchannels)
+-	 || (pfh.nchannels > 32)
+-	 || (pfh.norders > 256) || (!pfh.norders)
+-	 || (!pfh.nsamples) || (pfh.nsamples > 255)
+-	 || (!pfh.npatterns) || (pfh.npatterns > 128)
+-	 || (SIZEOF_PTMFILEHEADER+pfh.nsamples*SIZEOF_PTMSAMPLE >= (int)dwMemLength)) return FALSE;
+-	memcpy(m_szNames[0], pfh.songname, 28);
+-	m_szNames[0][28] = 0;
+-	m_nType = MOD_TYPE_PTM;
+-	m_nChannels = pfh.nchannels;
+-	m_nSamples = (pfh.nsamples < MAX_SAMPLES) ? pfh.nsamples : MAX_SAMPLES-1;
+-	dwMemPos = SIZEOF_PTMFILEHEADER;
+-	nOrders = (pfh.norders < MAX_ORDERS) ? pfh.norders : MAX_ORDERS-1;
+-	memcpy(Order, pfh.orders, nOrders);
+-	for (UINT ipan=0; ipan<m_nChannels; ipan++)
+-	{
+-		ChnSettings[ipan].nVolume = 64;
+-		ChnSettings[ipan].nPan = ((pfh.chnpan[ipan] & 0x0F) << 4) + 4;
+-	}
+-	for (UINT ismp=0; ismp<m_nSamples; ismp++, dwMemPos += SIZEOF_PTMSAMPLE)
+-	{
+-		MODINSTRUMENT *pins = &Ins[ismp+1];
+-		PTMSAMPLE *psmp = (PTMSAMPLE *)(lpStream+dwMemPos);
+-
+-		lstrcpyn(m_szNames[ismp+1], psmp->samplename, 28);
+-		memcpy(pins->name, psmp->filename, 12);
+-		pins->name[12] = 0;
+-		pins->nGlobalVol = 64;
+-		pins->nPan = 128;
+-		pins->nVolume = psmp->volume << 2;
+-		pins->nC4Speed = bswapLE16(psmp->nC4Spd) << 1;
+-		pins->uFlags = 0;
+-		if ((psmp->sampletype & 3) == 1)
+-		{
+-			UINT smpflg = RS_PCM8D;
+-			DWORD samplepos;
+-			pins->nLength = bswapLE32(*psmp->length);
+-			pins->nLoopStart = bswapLE32(*psmp->loopbeg);
+-			pins->nLoopEnd = bswapLE32(*psmp->loopend);
+-			samplepos = bswapLE32(*psmp->fileofs);
+-			if (psmp->sampletype & 4) pins->uFlags |= CHN_LOOP;
+-			if (psmp->sampletype & 8) pins->uFlags |= CHN_PINGPONGLOOP;
+-			if (psmp->sampletype & 16)
+-			{
+-				pins->uFlags |= CHN_16BIT;
+-				pins->nLength >>= 1;
+-				pins->nLoopStart >>= 1;
+-				pins->nLoopEnd >>= 1;
+-				smpflg = RS_PTM8DTO16;
+-			}
+-			if ((pins->nLength) && (samplepos) && (samplepos < dwMemLength))
+-			{
+-				ReadSample(pins, smpflg, (LPSTR)(lpStream+samplepos), dwMemLength-samplepos);
+-			}
+-		}
+-	}
+-	// Reading Patterns
+-	for (UINT ipat=0; ipat<pfh.npatterns; ipat++)
+-	{
+-		dwMemPos = ((UINT)pfh.patseg[ipat]) << 4;
+-		if ((!dwMemPos) || (dwMemPos >= dwMemLength)) continue;
+-		PatternSize[ipat] = 64;
+-		PatternAllocSize[ipat] = 64;
+-		if ((Patterns[ipat] = AllocatePattern(64, m_nChannels)) == NULL) break;
+-		//
+-		MODCOMMAND *m = Patterns[ipat];
+-		for (UINT row=0; ((row < 64) && (dwMemPos < dwMemLength)); )
+-		{
+-			UINT b = lpStream[dwMemPos++];
+-
+-			if (dwMemPos >= dwMemLength) break;
+-			if (b)
+-			{
+-				UINT nChn = b & 0x1F;
+-
+-				if (b & 0x20)
+-				{
+-					if (dwMemPos + 2 > dwMemLength) break;
+-					m[nChn].note = lpStream[dwMemPos++];
+-					m[nChn].instr = lpStream[dwMemPos++];
+-				}
+-				if (b & 0x40)
+-				{
+-					if (dwMemPos + 2 > dwMemLength) break;
+-					m[nChn].command = lpStream[dwMemPos++];
+-					m[nChn].param = lpStream[dwMemPos++];
+-					if ((m[nChn].command == 0x0E) && ((m[nChn].param & 0xF0) == 0x80))
+-					{
+-						m[nChn].command = CMD_S3MCMDEX;
+-					} else
+-					if (m[nChn].command < 0x10)
+-					{
+-						ConvertModCommand(&m[nChn]);
+-					} else
+-					{
+-						switch(m[nChn].command)
+-						{
+-						case 16:
+-							m[nChn].command = CMD_GLOBALVOLUME;
+-							break;
+-						case 17:
+-							m[nChn].command = CMD_RETRIG;
+-							break;
+-						case 18:
+-							m[nChn].command = CMD_FINEVIBRATO;
+-							break;
+-						default:
+-							m[nChn].command = 0;
+-						}
+-					}
+-				}
+-				if (b & 0x80)
+-				{
+-					if (dwMemPos >= dwMemLength) break;
+-					m[nChn].volcmd = VOLCMD_VOLUME;
+-					m[nChn].vol = lpStream[dwMemPos++];
+-				}
+-			} else
+-			{
+-				row++;
+-				m += m_nChannels;
+-			}
+-		}
+-	}
+-	return TRUE;
+-}
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_s3m.cxx audacious-plugins-2.5.4/src/modplug/load_s3m.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_s3m.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_s3m.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,406 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>,
+- *          Adam Goode       <adam at evdebs.org> (endian and char fixes for PPC)
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#pragma warning(disable:4244)
+-
+-extern WORD S3MFineTuneTable[16];
+-
+-//////////////////////////////////////////////////////
+-// ScreamTracker S3M file support
+-
+-typedef struct tagS3MSAMPLESTRUCT
+-{
+-	BYTE type;
+-	CHAR dosname[12];
+-	BYTE hmem;
+-	WORD memseg;
+-	DWORD length;
+-	DWORD loopbegin;
+-	DWORD loopend;
+-	BYTE vol;
+-	BYTE bReserved;
+-	BYTE pack;
+-	BYTE flags;
+-	DWORD finetune;
+-	DWORD dwReserved;
+-	WORD intgp;
+-	WORD int512;
+-	DWORD lastused;
+-	CHAR name[28];
+-	CHAR scrs[4];
+-} S3MSAMPLESTRUCT;
+-
+-
+-typedef struct tagS3MFILEHEADER
+-{
+-	CHAR name[28];
+-	BYTE b1A;
+-	BYTE type;
+-	WORD reserved1;
+-	WORD ordnum;
+-	WORD insnum;
+-	WORD patnum;
+-	WORD flags;
+-	WORD cwtv;
+-	WORD version;
+-	DWORD scrm;	// "SCRM" = 0x4D524353
+-	BYTE globalvol;
+-	BYTE speed;
+-	BYTE tempo;
+-	BYTE mastervol;
+-	BYTE ultraclicks;
+-	BYTE panning_present;
+-	BYTE reserved2[8];
+-	WORD special;
+-	BYTE channels[32];
+-} S3MFILEHEADER;
+-
+-
+-void CSoundFile::S3MConvert(MODCOMMAND *m, BOOL bIT) const
+-//--------------------------------------------------------
+-{
+-	UINT command = m->command;
+-	UINT param = m->param;
+-	switch (command + 0x40)
+-	{
+-	case 'A':	command = CMD_SPEED; break;
+-	case 'B':	command = CMD_POSITIONJUMP; break;
+-	case 'C':	command = CMD_PATTERNBREAK; if (!bIT) param = (param >> 4) * 10 + (param & 0x0F); break;
+-	case 'D':	command = CMD_VOLUMESLIDE; break;
+-	case 'E':	command = CMD_PORTAMENTODOWN; break;
+-	case 'F':	command = CMD_PORTAMENTOUP; break;
+-	case 'G':	command = CMD_TONEPORTAMENTO; break;
+-	case 'H':	command = CMD_VIBRATO; break;
+-	case 'I':	command = CMD_TREMOR; break;
+-	case 'J':	command = CMD_ARPEGGIO; break;
+-	case 'K':	command = CMD_VIBRATOVOL; break;
+-	case 'L':	command = CMD_TONEPORTAVOL; break;
+-	case 'M':	command = CMD_CHANNELVOLUME; break;
+-	case 'N':	command = CMD_CHANNELVOLSLIDE; break;
+-	case 'O':	command = CMD_OFFSET; break;
+-	case 'P':	command = CMD_PANNINGSLIDE; break;
+-	case 'Q':	command = CMD_RETRIG; break;
+-	case 'R':	command = CMD_TREMOLO; break;
+-	case 'S':	command = CMD_S3MCMDEX; break;
+-	case 'T':	command = CMD_TEMPO; break;
+-	case 'U':	command = CMD_FINEVIBRATO; break;
+-	case 'V':	command = CMD_GLOBALVOLUME; if (!bIT) param *= 2; break;
+-	case 'W':	command = CMD_GLOBALVOLSLIDE; break;
+-	case 'X':	command = CMD_PANNING8; break;
+-	case 'Y':	command = CMD_PANBRELLO; break;
+-	case 'Z':	command = CMD_MIDI; break;
+-	default:	command = 0;
+-	}
+-	m->command = command;
+-	m->param = param;
+-}
+-
+-
+-void CSoundFile::S3MSaveConvert(UINT *pcmd, UINT *pprm, BOOL bIT) const
+-//---------------------------------------------------------------------
+-{
+-	UINT command = *pcmd;
+-	UINT param = *pprm;
+-	switch(command)
+-	{
+-	case CMD_SPEED:				command = 'A'; break;
+-	case CMD_POSITIONJUMP:		command = 'B'; break;
+-	case CMD_PATTERNBREAK:		command = 'C'; if (!bIT) param = ((param / 10) << 4) + (param % 10); break;
+-	case CMD_VOLUMESLIDE:		command = 'D'; break;
+-	case CMD_PORTAMENTODOWN:	command = 'E'; if ((param >= 0xE0) && (m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM))) param = 0xDF; break;
+-	case CMD_PORTAMENTOUP:		command = 'F'; if ((param >= 0xE0) && (m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM))) param = 0xDF; break;
+-	case CMD_TONEPORTAMENTO:	command = 'G'; break;
+-	case CMD_VIBRATO:			command = 'H'; break;
+-	case CMD_TREMOR:			command = 'I'; break;
+-	case CMD_ARPEGGIO:			command = 'J'; break;
+-	case CMD_VIBRATOVOL:		command = 'K'; break;
+-	case CMD_TONEPORTAVOL:		command = 'L'; break;
+-	case CMD_CHANNELVOLUME:		command = 'M'; break;
+-	case CMD_CHANNELVOLSLIDE:	command = 'N'; break;
+-	case CMD_OFFSET:			command = 'O'; break;
+-	case CMD_PANNINGSLIDE:		command = 'P'; break;
+-	case CMD_RETRIG:			command = 'Q'; break;
+-	case CMD_TREMOLO:			command = 'R'; break;
+-	case CMD_S3MCMDEX:			command = 'S'; break;
+-	case CMD_TEMPO:				command = 'T'; break;
+-	case CMD_FINEVIBRATO:		command = 'U'; break;
+-	case CMD_GLOBALVOLUME:		command = 'V'; if (!bIT) param >>= 1;break;
+-	case CMD_GLOBALVOLSLIDE:	command = 'W'; break;
+-	case CMD_PANNING8:			
+-		command = 'X';
+-		if ((bIT) && (m_nType != MOD_TYPE_IT) && (m_nType != MOD_TYPE_XM))
+-		{
+-			if (param == 0xA4) { command = 'S'; param = 0x91; }	else
+-			if (param <= 0x80) { param <<= 1; if (param > 255) param = 255; } else
+-			command = param = 0;
+-		} else
+-		if ((!bIT) && ((m_nType == MOD_TYPE_IT) || (m_nType == MOD_TYPE_XM)))
+-		{
+-			param >>= 1;
+-		}
+-		break;
+-	case CMD_PANBRELLO:			command = 'Y'; break;
+-	case CMD_MIDI:				command = 'Z'; break;
+-	case CMD_XFINEPORTAUPDOWN:
+-		if (param & 0x0F) switch(param & 0xF0)
+-		{
+-		case 0x10:	command = 'F'; param = (param & 0x0F) | 0xE0; break;
+-		case 0x20:	command = 'E'; param = (param & 0x0F) | 0xE0; break;
+-		case 0x90:	command = 'S'; break;
+-		default:	command = param = 0;
+-		} else command = param = 0;
+-		break;
+-	case CMD_MODCMDEX:
+-		command = 'S';
+-		switch(param & 0xF0)
+-		{
+-		case 0x00:	command = param = 0; break;
+-		case 0x10:	command = 'F'; param |= 0xF0; break;
+-		case 0x20:	command = 'E'; param |= 0xF0; break;
+-		case 0x30:	param = (param & 0x0F) | 0x10; break;
+-		case 0x40:	param = (param & 0x0F) | 0x30; break;
+-		case 0x50:	param = (param & 0x0F) | 0x20; break;
+-		case 0x60:	param = (param & 0x0F) | 0xB0; break;
+-		case 0x70:	param = (param & 0x0F) | 0x40; break;
+-		case 0x90:	command = 'Q'; param &= 0x0F; break;
+-		case 0xA0:	if (param & 0x0F) { command = 'D'; param = (param << 4) | 0x0F; } else command=param=0; break;
+-		case 0xB0:	if (param & 0x0F) { command = 'D'; param |= 0xF0; } else command=param=0; break;
+-		}
+-		break;
+-	default:	command = param = 0;
+-	}
+-	command &= ~0x40;
+-	*pcmd = command;
+-	*pprm = param;
+-}
+-
+-
+-BOOL CSoundFile::ReadS3M(const BYTE *lpStream, DWORD dwMemLength)
+-//---------------------------------------------------------------
+-{
+-	UINT insnum,patnum,nins,npat;
+-	DWORD insfile[128];
+-	WORD ptr[256];
+-	BYTE s[1024];
+-	DWORD dwMemPos;
+-	BYTE insflags[128], inspack[128];
+-	S3MFILEHEADER psfh = *(S3MFILEHEADER *)lpStream;
+-
+-	psfh.reserved1 = bswapLE16(psfh.reserved1);
+-	psfh.ordnum = bswapLE16(psfh.ordnum);
+-	psfh.insnum = bswapLE16(psfh.insnum);
+-	psfh.patnum = bswapLE16(psfh.patnum);
+-	psfh.flags = bswapLE16(psfh.flags);
+-	psfh.cwtv = bswapLE16(psfh.cwtv);
+-	psfh.version = bswapLE16(psfh.version);
+-	psfh.scrm = bswapLE32(psfh.scrm);
+-	psfh.special = bswapLE16(psfh.special);
+-
+-	if ((!lpStream) || (dwMemLength <= sizeof(S3MFILEHEADER)+sizeof(S3MSAMPLESTRUCT)+64)) return FALSE;
+-	if (psfh.scrm != 0x4D524353) return FALSE;
+-	dwMemPos = 0x60;
+-	m_nType = MOD_TYPE_S3M;
+-	memset(m_szNames,0,sizeof(m_szNames));
+-	memcpy(m_szNames[0], psfh.name, 28);
+-	// Speed
+-	m_nDefaultSpeed = psfh.speed;
+-	if (m_nDefaultSpeed < 1) m_nDefaultSpeed = 6;
+-	if (m_nDefaultSpeed > 0x1F) m_nDefaultSpeed = 0x1F;
+-	// Tempo
+-	m_nDefaultTempo = psfh.tempo;
+-	if (m_nDefaultTempo < 40) m_nDefaultTempo = 40;
+-	if (m_nDefaultTempo > 240) m_nDefaultTempo = 240;
+-	// Global Volume
+-	m_nDefaultGlobalVolume = psfh.globalvol << 2;
+-	if ((!m_nDefaultGlobalVolume) || (m_nDefaultGlobalVolume > 256)) m_nDefaultGlobalVolume = 256;
+-	m_nSongPreAmp = psfh.mastervol & 0x7F;
+-	// Channels
+-	m_nChannels = 4;
+-	for (UINT ich=0; ich<32; ich++)
+-	{
+-		ChnSettings[ich].nPan = 128;
+-		ChnSettings[ich].nVolume = 64;
+-
+-		ChnSettings[ich].dwFlags = CHN_MUTE;
+-		if (psfh.channels[ich] != 0xFF)
+-		{
+-			m_nChannels = ich+1;
+-			UINT b = psfh.channels[ich] & 0x0F;
+-			ChnSettings[ich].nPan = (b & 8) ? 0xC0 : 0x40;
+-			ChnSettings[ich].dwFlags = 0;
+-		}
+-	}
+-	if (m_nChannels < 4) m_nChannels = 4;
+-	if ((psfh.cwtv < 0x1320) || (psfh.flags & 0x40)) m_dwSongFlags |= SONG_FASTVOLSLIDES;
+-	// Reading pattern order
+-	UINT iord = psfh.ordnum;
+-	if (iord<1) iord = 1;
+-	if (iord > MAX_ORDERS) iord = MAX_ORDERS;
+-	if (iord)
+-	{
+-		memcpy(Order, lpStream+dwMemPos, iord);
+-		dwMemPos += iord;
+-	}
+-	if ((iord & 1) && (lpStream[dwMemPos] == 0xFF)) dwMemPos++;
+-	// Reading file pointers
+-	insnum = nins = psfh.insnum;
+-	if (insnum >= MAX_SAMPLES) insnum = MAX_SAMPLES-1;
+-	m_nSamples = insnum;
+-	patnum = npat = psfh.patnum;
+-	if (patnum > MAX_PATTERNS) patnum = MAX_PATTERNS;
+-	memset(ptr, 0, sizeof(ptr));
+-	if (nins+npat)
+-	{
+-		memcpy(ptr, lpStream+dwMemPos, 2*(nins+npat));
+-		dwMemPos += 2*(nins+npat);
+-		for (UINT j = 0; j < (nins+npat); ++j) {
+-		        ptr[j] = bswapLE16(ptr[j]);
+-		}
+-		if (psfh.panning_present == 252)
+-		{
+-			const BYTE *chnpan = lpStream+dwMemPos;
+-			for (UINT i=0; i<32; i++) if (chnpan[i] & 0x20)
+-			{
+-				ChnSettings[i].nPan = ((chnpan[i] & 0x0F) << 4) + 8;
+-			}
+-		}
+-	}
+-	if (!m_nChannels) return TRUE;
+-	// Reading instrument headers
+-	memset(insfile, 0, sizeof(insfile));
+-	for (UINT iSmp=1; iSmp<=insnum; iSmp++)
+-	{
+-		UINT nInd = ((DWORD)ptr[iSmp-1])*16;
+-		if ((!nInd) || (nInd + 0x50 > dwMemLength)) continue;
+-		memcpy(s, lpStream+nInd, 0x50);
+-		memcpy(Ins[iSmp].name, s+1, 12);
+-		insflags[iSmp-1] = s[0x1F];
+-		inspack[iSmp-1] = s[0x1E];
+-		s[0x4C] = 0;
+-		lstrcpy(m_szNames[iSmp], (LPCSTR)&s[0x30]);
+-		if ((s[0]==1) && (s[0x4E]=='R') && (s[0x4F]=='S'))
+-		{
+-			UINT j = bswapLE32(*((LPDWORD)(s+0x10)));
+-			if (j > MAX_SAMPLE_LENGTH) j = MAX_SAMPLE_LENGTH;
+-			if (j < 2) j = 0;
+-			Ins[iSmp].nLength = j;
+-			j = bswapLE32(*((LPDWORD)(s+0x14)));
+-			if (j >= Ins[iSmp].nLength) j = Ins[iSmp].nLength - 1;
+-			Ins[iSmp].nLoopStart = j;
+-			j = bswapLE32(*((LPDWORD)(s+0x18)));
+-			if (j > MAX_SAMPLE_LENGTH) j = MAX_SAMPLE_LENGTH;
+-			if (j < 2) j = 0;
+-			if (j > Ins[iSmp].nLength) j = Ins[iSmp].nLength;
+-			Ins[iSmp].nLoopEnd = j;
+-			j = s[0x1C];
+-			if (j > 64) j = 64;
+-			Ins[iSmp].nVolume = j << 2;
+-			Ins[iSmp].nGlobalVol = 64;
+-			if (s[0x1F]&1) Ins[iSmp].uFlags |= CHN_LOOP;
+-			j = bswapLE32(*((LPDWORD)(s+0x20)));
+-			if (!j) j = 8363;
+-			if (j < 1024) j = 1024;
+-			Ins[iSmp].nC4Speed = j;
+-			insfile[iSmp] = ((DWORD)bswapLE16(*((LPWORD)(s+0x0E)))) << 4;
+-			insfile[iSmp] += ((DWORD)(BYTE)s[0x0D]) << 20;
+-			if (insfile[iSmp] > dwMemLength) insfile[iSmp] &= 0xFFFF;
+-			if ((Ins[iSmp].nLoopStart >= Ins[iSmp].nLoopEnd) || (Ins[iSmp].nLoopEnd - Ins[iSmp].nLoopStart < 8))
+-				Ins[iSmp].nLoopStart = Ins[iSmp].nLoopEnd = 0;
+-			Ins[iSmp].nPan = 0x80;
+-		}
+-	}
+-	// Reading patterns
+-	for (UINT iPat=0; iPat<patnum; iPat++)
+-	{
+-                UINT nInd = ((DWORD)ptr[nins+iPat]) << 4;
+-                // if the parapointer is zero, the pattern is blank (so ignore it)
+-                if (nInd == 0)
+-                        continue;
+-                if (nInd + 0x40 > dwMemLength) continue;
+-		WORD len = bswapLE16(*((WORD *)(lpStream+nInd)));
+-		nInd += 2;
+-		PatternSize[iPat] = 64;
+-		PatternAllocSize[iPat] = 64;
+-		if ((!len) || (nInd + len > dwMemLength - 6)
+-		 || ((Patterns[iPat] = AllocatePattern(64, m_nChannels)) == NULL)) continue;
+-		LPBYTE src = (LPBYTE)(lpStream+nInd);
+-		// Unpacking pattern
+-		MODCOMMAND *p = Patterns[iPat];
+-		UINT row = 0;
+-		UINT j = 0;
+-		while (j < len)
+-		{
+-			BYTE b = src[j++];
+-			if (!b)
+-			{
+-				if (++row >= 64) break;
+-			} else
+-			{
+-				UINT chn = b & 0x1F;
+-				if (chn < m_nChannels)
+-				{
+-					MODCOMMAND *m = &p[row*m_nChannels+chn];
+-					if (b & 0x20)
+-					{
+-						m->note = src[j++];
+-						if (m->note < 0xF0) m->note = (m->note & 0x0F) + 12*(m->note >> 4) + 13;
+-						else if (m->note == 0xFF) m->note = 0;
+-						m->instr = src[j++];
+-					}
+-					if (b & 0x40)
+-					{
+-						UINT vol = src[j++];
+-						if ((vol >= 128) && (vol <= 192))
+-						{
+-							vol -= 128;
+-							m->volcmd = VOLCMD_PANNING;
+-						} else
+-						{
+-							if (vol > 64) vol = 64;
+-							m->volcmd = VOLCMD_VOLUME;
+-						}
+-						m->vol = vol;
+-					}
+-					if (b & 0x80)
+-					{
+-						m->command = src[j++];
+-						m->param = src[j++];
+-						if (m->command) S3MConvert(m, FALSE);
+-					}
+-				} else
+-				{
+-					if (b & 0x20) j += 2;
+-					if (b & 0x40) j++;
+-					if (b & 0x80) j += 2;
+-				}
+-				if (j >= len) break;
+-			}
+-		}
+-	}
+-	// Reading samples
+-	for (UINT iRaw=1; iRaw<=insnum; iRaw++) if ((Ins[iRaw].nLength) && (insfile[iRaw]))
+-	{
+-		UINT flags;
+-		if (insflags[iRaw-1] & 4)
+-			flags = (psfh.version == 1) ? RS_PCM16S : RS_PCM16U;
+-		else
+-			flags = (psfh.version == 1) ? RS_PCM8S : RS_PCM8U;
+-		if (insflags[iRaw-1] & 2) flags |= RSF_STEREO;
+-		if (inspack[iRaw-1] == 4) flags = RS_ADPCM4;
+-		dwMemPos = insfile[iRaw];
+-		dwMemPos += ReadSample(&Ins[iRaw], flags, (LPSTR)(lpStream + dwMemPos), dwMemLength - dwMemPos);
+-	}
+-	m_nMinPeriod = 64;
+-	m_nMaxPeriod = 32767;
+-	if (psfh.flags & 0x10) m_dwSongFlags |= SONG_AMIGALIMITS;
+-	return TRUE;
+-}
+-
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_stm.cxx audacious-plugins-2.5.4/src/modplug/load_stm.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_stm.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_stm.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,187 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#pragma warning(disable:4244)
+-
+-#pragma pack(1)
+-
+-typedef struct tagSTMNOTE
+-{
+-	BYTE note;
+-	BYTE insvol;
+-	BYTE volcmd;
+-	BYTE cmdinf;
+-} STMNOTE;
+-
+-
+-// Raw STM sampleinfo struct:
+-typedef struct tagSTMSAMPLE
+-{
+-	CHAR filename[14];	// Can't have long comments - just filename comments :)
+-	WORD reserved;		// ISA in memory when in ST 2
+-	WORD length;		// Sample length
+-	WORD loopbeg;		// Loop start point
+-	WORD loopend;		// Loop end point
+-	BYTE volume;		// Volume
+-	BYTE reserved2;		// More reserved crap
+-	WORD c2spd;			// Good old c2spd
+-	BYTE reserved3[6];	// Yet more of PSi's reserved crap
+-} STMSAMPLE;
+-
+-
+-// Raw STM header struct:
+-typedef struct tagSTMHEADER
+-{
+-        char songname[20];      // changed from CHAR
+-	char trackername[8];	// !SCREAM! for ST 2.xx  // changed from CHAR
+-	CHAR unused;			// 0x1A
+-	CHAR filetype;			// 1=song, 2=module (only 2 is supported, of course) :)
+-	CHAR ver_major;			// Like 2
+-	CHAR ver_minor;			// "ditto"
+-	BYTE inittempo;			// initspeed= stm inittempo>>4
+-	BYTE numpat;			// number of patterns
+-	BYTE globalvol;			// <- WoW! a RiGHT TRiANGLE =8*)
+-	BYTE reserved[13];		// More of PSi's internal crap
+-	STMSAMPLE sample[31];	// STM sample data
+-	BYTE patorder[128];		// Docs say 64 - actually 128
+-} STMHEADER;
+-
+-#pragma pack()
+-
+-
+-
+-BOOL CSoundFile::ReadSTM(const BYTE *lpStream, DWORD dwMemLength)
+-//---------------------------------------------------------------
+-{
+-	STMHEADER *phdr = (STMHEADER *)lpStream;
+-	DWORD dwMemPos = 0;
+-	
+-	if ((!lpStream) || (dwMemLength < sizeof(STMHEADER))) return FALSE;
+-	if ((phdr->filetype != 2) || (phdr->unused != 0x1A)
+-	 || ((strnicmp(phdr->trackername, "!SCREAM!", 8))
+-	  && (strnicmp(phdr->trackername, "BMOD2STM", 8)))) return FALSE;
+-	memcpy(m_szNames[0], phdr->songname, 20);
+-	// Read STM header
+-	m_nType = MOD_TYPE_STM;
+-	m_nSamples = 31;
+-	m_nChannels = 4;
+-	m_nInstruments = 0;
+-	m_nMinPeriod = 64;
+-	m_nMaxPeriod = 0x7FFF;
+-	m_nDefaultSpeed = phdr->inittempo >> 4;
+-	if (m_nDefaultSpeed < 1) m_nDefaultSpeed = 1;
+-	m_nDefaultTempo = 125;
+-	m_nDefaultGlobalVolume = phdr->globalvol << 2;
+-	if (m_nDefaultGlobalVolume > 256) m_nDefaultGlobalVolume = 256;
+-	memcpy(Order, phdr->patorder, 128);
+-	// Setting up channels
+-	for (UINT nSet=0; nSet<4; nSet++)
+-	{
+-		ChnSettings[nSet].dwFlags = 0;
+-		ChnSettings[nSet].nVolume = 64;
+-		ChnSettings[nSet].nPan = (nSet & 1) ? 0x40 : 0xC0;
+-	}
+-	// Reading samples
+-	for (UINT nIns=0; nIns<31; nIns++)
+-	{
+-		MODINSTRUMENT *pIns = &Ins[nIns+1];
+-		STMSAMPLE *pStm = &phdr->sample[nIns];  // STM sample data
+-		memcpy(pIns->name, pStm->filename, 13);
+-		memcpy(m_szNames[nIns+1], pStm->filename, 12);
+-		pIns->nC4Speed = bswapLE16(pStm->c2spd);
+-		pIns->nGlobalVol = 64;
+-		pIns->nVolume = pStm->volume << 2;
+-		if (pIns->nVolume > 256) pIns->nVolume = 256;
+-		pIns->nLength = bswapLE16(pStm->length);
+-		if ((pIns->nLength < 4) || (!pIns->nVolume)) pIns->nLength = 0;
+-		pIns->nLoopStart = bswapLE16(pStm->loopbeg);
+-		pIns->nLoopEnd = bswapLE16(pStm->loopend);
+-		if ((pIns->nLoopEnd > pIns->nLoopStart) && (pIns->nLoopEnd != 0xFFFF)) pIns->uFlags |= CHN_LOOP;
+-	}
+-	dwMemPos = sizeof(STMHEADER);
+-	for (UINT nOrd=0; nOrd<MAX_ORDERS; nOrd++) if (Order[nOrd] >= 99) Order[nOrd] = 0xFF;
+-	UINT nPatterns = phdr->numpat;
+-	for (UINT nPat=0; nPat<nPatterns; nPat++)
+-	{
+-		if (dwMemPos + 64*4*4 > dwMemLength) return TRUE;
+-		PatternSize[nPat] = 64;
+-		PatternAllocSize[nPat] = 64;
+-		if ((Patterns[nPat] = AllocatePattern(64, m_nChannels)) == NULL) return TRUE;
+-		MODCOMMAND *m = Patterns[nPat];
+-		STMNOTE *p = (STMNOTE *)(lpStream + dwMemPos);
+-		for (UINT n=0; n<64*4; n++, p++, m++)
+-		{
+-			UINT note,ins,vol,cmd;
+-			// extract the various information from the 4 bytes that
+-			// make up a single note
+-			note = p->note;
+-			ins = p->insvol >> 3;
+-			vol = (p->insvol & 0x07) + (p->volcmd >> 1);
+-			cmd = p->volcmd & 0x0F;
+-			if ((ins) && (ins < 32)) m->instr = ins;
+-			// special values of [SBYTE0] are handled here ->
+-			// we have no idea if these strange values will ever be encountered
+-			// but it appears as though stms sound correct.
+-			if ((note == 0xFE) || (note == 0xFC)) m->note = 0xFE; else
+-			// if note < 251, then all three bytes are stored in the file
+-			if (note < 0xFC) m->note = (note >> 4)*12 + (note&0xf) + 37;
+-			if (vol <= 64) { m->volcmd = VOLCMD_VOLUME; m->vol = vol; }
+-			m->param = p->cmdinf;
+-			switch(cmd)
+-			{
+-			// Axx set speed to xx
+-			case 1:	m->command = CMD_SPEED; m->param >>= 4; break;
+-			// Bxx position jump
+-			case 2:	m->command = CMD_POSITIONJUMP; break;
+-			// Cxx patternbreak to row xx
+-			case 3:	m->command = CMD_PATTERNBREAK; m->param = (m->param & 0xF0) * 10 + (m->param & 0x0F);	break;
+-			// Dxy volumeslide
+-			case 4:	m->command = CMD_VOLUMESLIDE; break;
+-			// Exy toneslide down
+-			case 5:	m->command = CMD_PORTAMENTODOWN; break;
+-			// Fxy toneslide up
+-			case 6:	m->command = CMD_PORTAMENTOUP; break;
+-			// Gxx Tone portamento,speed xx
+-			case 7:	m->command = CMD_TONEPORTAMENTO; break;
+-			// Hxy vibrato
+-			case 8:	m->command = CMD_VIBRATO; break;
+-			// Ixy tremor, ontime x, offtime y
+-			case 9:	m->command = CMD_TREMOR; break;
+-			// Jxy arpeggio
+-			case 10: m->command = CMD_ARPEGGIO; break;
+-			// Kxy Dual command H00 & Dxy
+-			case 11: m->command = CMD_VIBRATOVOL; break;
+-			// Lxy Dual command G00 & Dxy
+-			case 12: m->command = CMD_TONEPORTAVOL; break;
+-			// Xxx amiga command 8xx
+-			case 0x18:	m->command = CMD_PANNING8; break;
+-			default:
+-				m->command = m->param = 0;
+-			}
+-		}
+-		dwMemPos += 64*4*4;
+-	}
+-	// Reading Samples
+-	for (UINT nSmp=1; nSmp<=31; nSmp++)
+-	{
+-		MODINSTRUMENT *pIns = &Ins[nSmp];
+-		dwMemPos = (dwMemPos + 15) & (~15);
+-		if (pIns->nLength)
+-		{
+-			UINT nPos = ((UINT)phdr->sample[nSmp-1].reserved) << 4;
+-			if ((nPos >= sizeof(STMHEADER)) && (nPos+pIns->nLength <= dwMemLength)) dwMemPos = nPos;
+-			if (dwMemPos < dwMemLength)
+-			{
+-				dwMemPos += ReadSample(pIns, RS_PCM8S, (LPSTR)(lpStream+dwMemPos),dwMemLength-dwMemPos);
+-			}
+-		}
+-	}
+-	return TRUE;
+-}
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_ult.cxx audacious-plugins-2.5.4/src/modplug/load_ult.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_ult.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_ult.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,223 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-//#pragma warning(disable:4244)
+-
+-#define ULT_16BIT   0x04
+-#define ULT_LOOP    0x08
+-#define ULT_BIDI    0x10
+-
+-#pragma pack(1)
+-
+-// Raw ULT header struct:
+-typedef struct tagULTHEADER
+-{
+-        char id[15];             // changed from CHAR
+-        char songtitle[32];      // changed from CHAR
+-	BYTE reserved;
+-} ULTHEADER;
+-
+-
+-// Raw ULT sampleinfo struct:
+-typedef struct tagULTSAMPLE
+-{
+-	CHAR samplename[32];
+-	CHAR dosname[12];
+-	LONG loopstart;
+-	LONG loopend;
+-	LONG sizestart;
+-	LONG sizeend;
+-	BYTE volume;
+-	BYTE flags;
+-	WORD finetune;
+-} ULTSAMPLE;
+-
+-#pragma pack()
+-
+-
+-BOOL CSoundFile::ReadUlt(const BYTE *lpStream, DWORD dwMemLength)
+-//---------------------------------------------------------------
+-{
+-	ULTHEADER *pmh = (ULTHEADER *)lpStream;
+-	ULTSAMPLE *pus;
+-	UINT nos, nop;
+-	DWORD dwMemPos = 0;
+-
+-	// try to read module header
+-	if ((!lpStream) || (dwMemLength < 0x100)) return FALSE;
+-	if (strncmp(pmh->id,"MAS_UTrack_V00",14)) return FALSE;
+-	// Warning! Not supported ULT format, trying anyway
+-	// if ((pmh->id[14] < '1') || (pmh->id[14] > '4')) return FALSE;
+-	m_nType = MOD_TYPE_ULT;
+-	m_nDefaultSpeed = 6;
+-	m_nDefaultTempo = 125;
+-	memcpy(m_szNames[0], pmh->songtitle, 32);
+-	// read songtext
+-	dwMemPos = sizeof(ULTHEADER);
+-	if ((pmh->reserved) && (dwMemPos + pmh->reserved * 32 < dwMemLength))
+-	{
+-		UINT len = pmh->reserved * 32;
+-		m_lpszSongComments = new char[len + 1 + pmh->reserved];
+-		if (m_lpszSongComments)
+-		{
+-			for (UINT l=0; l<pmh->reserved; l++)
+-			{
+-				memcpy(m_lpszSongComments+l*33, lpStream+dwMemPos+l*32, 32);
+-				m_lpszSongComments[l*33+32] = 0x0D;
+-			}
+-			m_lpszSongComments[len] = 0;
+-		}
+-		dwMemPos += len;
+-	}
+-	if (dwMemPos >= dwMemLength) return TRUE;
+-	nos = lpStream[dwMemPos++];
+-	m_nSamples = nos;
+-	if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES-1;
+-	UINT smpsize = 64;
+-	if (pmh->id[14] >= '4')	smpsize += 2;
+-	if (dwMemPos + nos*smpsize + 256 + 2 > dwMemLength) return TRUE;
+-	for (UINT ins=1; ins<=nos; ins++, dwMemPos+=smpsize) if (ins<=m_nSamples)
+-	{
+-		pus	= (ULTSAMPLE *)(lpStream+dwMemPos);
+-		MODINSTRUMENT *pins = &Ins[ins];
+-		memcpy(m_szNames[ins], pus->samplename, 32);
+-		memcpy(pins->name, pus->dosname, 12);
+-		pins->nLoopStart = pus->loopstart;
+-		pins->nLoopEnd = pus->loopend;
+-		pins->nLength = pus->sizeend - pus->sizestart;
+-		pins->nVolume = pus->volume;
+-		pins->nGlobalVol = 64;
+-		pins->nC4Speed = 8363;
+-		if (pmh->id[14] >= '4')
+-		{
+-			pins->nC4Speed = pus->finetune;
+-		}
+-		if (pus->flags & ULT_LOOP) pins->uFlags |= CHN_LOOP;
+-		if (pus->flags & ULT_BIDI) pins->uFlags |= CHN_PINGPONGLOOP;
+-		if (pus->flags & ULT_16BIT)
+-		{
+-			pins->uFlags |= CHN_16BIT;
+-			pins->nLoopStart >>= 1;
+-			pins->nLoopEnd >>= 1;
+-		}
+-	}
+-	memcpy(Order, lpStream+dwMemPos, 256);
+-	dwMemPos += 256;
+-	m_nChannels = lpStream[dwMemPos] + 1;
+-	nop = lpStream[dwMemPos+1] + 1;
+-	dwMemPos += 2;
+-	if (m_nChannels > 32) m_nChannels = 32;
+-	// Default channel settings
+-	for (UINT nSet=0; nSet<m_nChannels; nSet++)
+-	{
+-		ChnSettings[nSet].nVolume = 64;
+-		ChnSettings[nSet].nPan = (nSet & 1) ? 0x40 : 0xC0;
+-	}
+-	// read pan position table for v1.5 and higher
+-	if(pmh->id[14]>='3')
+-	{
+-		if (dwMemPos + m_nChannels > dwMemLength) return TRUE;
+-		for(UINT t=0; t<m_nChannels; t++)
+-		{
+-			ChnSettings[t].nPan = (lpStream[dwMemPos++] << 4) + 8;
+-			if (ChnSettings[t].nPan > 256) ChnSettings[t].nPan = 256;
+-		}
+-	}
+-	// Allocating Patterns
+-	for (UINT nAllocPat=0; nAllocPat<nop; nAllocPat++)
+-	{
+-		if (nAllocPat < MAX_PATTERNS)
+-		{
+-			PatternSize[nAllocPat] = 64;
+-			PatternAllocSize[nAllocPat] = 64;
+-			Patterns[nAllocPat] = AllocatePattern(64, m_nChannels);
+-		}
+-	}
+-	// Reading Patterns
+-	for (UINT nChn=0; nChn<m_nChannels; nChn++)
+-	{
+-		for (UINT nPat=0; nPat<nop; nPat++)
+-		{
+-			MODCOMMAND *pat = NULL;
+-			
+-			if (nPat < MAX_PATTERNS)
+-			{
+-				pat = Patterns[nPat];
+-				if (pat) pat += nChn;
+-			}
+-			UINT row = 0;
+-			while (row < 64)
+-			{
+-				if (dwMemPos + 6 > dwMemLength) return TRUE;
+-				UINT rep = 1;
+-				UINT note = lpStream[dwMemPos++];
+-				if (note == 0xFC)
+-				{
+-					rep = lpStream[dwMemPos];
+-					note = lpStream[dwMemPos+1];
+-					dwMemPos += 2;
+-				}
+-				UINT instr = lpStream[dwMemPos++];
+-				UINT eff = lpStream[dwMemPos++];
+-				UINT dat1 = lpStream[dwMemPos++];
+-				UINT dat2 = lpStream[dwMemPos++];
+-				UINT cmd1 = eff & 0x0F;
+-				UINT cmd2 = eff >> 4;
+-				if (cmd1 == 0x0C) dat1 >>= 2; else
+-				if (cmd1 == 0x0B) { cmd1 = dat1 = 0; }
+-				if (cmd2 == 0x0C) dat2 >>= 2; else
+-				if (cmd2 == 0x0B) { cmd2 = dat2 = 0; }
+-				while ((rep != 0) && (row < 64))
+-				{
+-					if (pat)
+-					{
+-						pat->instr = instr;
+-						if (note) pat->note = note + 36;
+-						if (cmd1 | dat1)
+-						{
+-							if (cmd1 == 0x0C)
+-							{
+-								pat->volcmd = VOLCMD_VOLUME;
+-								pat->vol = dat1;
+-							} else
+-							{
+-								pat->command = cmd1;
+-								pat->param = dat1;
+-								ConvertModCommand(pat);
+-							}
+-						}
+-						if (cmd2 == 0x0C)
+-						{
+-							pat->volcmd = VOLCMD_VOLUME;
+-							pat->vol = dat2;
+-						} else
+-						if ((cmd2 | dat2) && (!pat->command))
+-						{
+-							pat->command = cmd2;
+-							pat->param = dat2;
+-							ConvertModCommand(pat);
+-						}
+-						pat += m_nChannels;
+-					}
+-					row++;
+-					rep--;
+-				}
+-			}
+-		}
+-	}
+-	// Reading Instruments
+-	for (UINT smp=1; smp<=m_nSamples; smp++) if (Ins[smp].nLength)
+-	{
+-		if (dwMemPos >= dwMemLength) return TRUE;
+-		UINT flags = (Ins[smp].uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S;
+-		dwMemPos += ReadSample(&Ins[smp], flags, (LPSTR)(lpStream+dwMemPos), dwMemLength - dwMemPos);
+-	}
+-	return TRUE;
+-}
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_umx.cxx audacious-plugins-2.5.4/src/modplug/load_umx.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_umx.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_umx.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,53 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-#define MODMAGIC_OFFSET	(20+31*30+130)
+-
+-
+-BOOL CSoundFile::ReadUMX(const BYTE *lpStream, DWORD dwMemLength)
+-//---------------------------------------------------------------
+-{
+-	if ((!lpStream) || (dwMemLength < 0x800)) return FALSE;
+-	// Rip Mods from UMX
+-	if ((bswapLE32(*((DWORD *)(lpStream+0x20))) < dwMemLength)
+-	 && (bswapLE32(*((DWORD *)(lpStream+0x18))) <= dwMemLength - 0x10)
+-	 && (bswapLE32(*((DWORD *)(lpStream+0x18))) >= dwMemLength - 0x200))
+-	{
+-		for (UINT uscan=0x40; uscan<0x500; uscan++)
+-		{
+-			DWORD dwScan = bswapLE32(*((DWORD *)(lpStream+uscan)));
+-			// IT
+-			if (dwScan == 0x4D504D49)
+-			{
+-				DWORD dwRipOfs = uscan;
+-				return ReadIT(lpStream + dwRipOfs, dwMemLength - dwRipOfs);
+-			}
+-			// S3M
+-			if (dwScan == 0x4D524353)
+-			{
+-				DWORD dwRipOfs = uscan - 44;
+-				return ReadS3M(lpStream + dwRipOfs, dwMemLength - dwRipOfs);
+-			}
+-			// XM
+-			if (!strnicmp((LPCSTR)(lpStream+uscan), "Extended Module", 15))
+-			{
+-				DWORD dwRipOfs = uscan;
+-				return ReadXM(lpStream + dwRipOfs, dwMemLength - dwRipOfs);
+-			}
+-			// MOD
+-			if ((uscan > MODMAGIC_OFFSET) && (dwScan == 0x2e4b2e4d))
+-			{
+-				DWORD dwRipOfs = uscan - MODMAGIC_OFFSET;
+-				return ReadMod(lpStream+dwRipOfs, dwMemLength-dwRipOfs);
+-			}
+-		}
+-	}
+-	return FALSE;
+-}
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_wav.cxx audacious-plugins-2.5.4/src/modplug/load_wav.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_wav.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_wav.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,248 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-#ifndef WAVE_FORMAT_EXTENSIBLE
+-#define WAVE_FORMAT_EXTENSIBLE	0xFFFE
+-#endif
+-
+-/////////////////////////////////////////////////////////////
+-// WAV file support
+-
+-BOOL CSoundFile::ReadWav(const BYTE *lpStream, DWORD dwMemLength)
+-//---------------------------------------------------------------
+-{
+-	DWORD dwMemPos = 0;
+-	WAVEFILEHEADER phdr;
+-	WAVEFORMATHEADER pfmt;
+-
+-	if ((!lpStream)
+-	|| (dwMemLength < (DWORD)(sizeof(WAVEFORMATHEADER)+sizeof(WAVEFILEHEADER))))
+-		return FALSE;
+-
+-	memcpy(&phdr, lpStream, sizeof(phdr));
+-	memcpy(&pfmt, lpStream+sizeof(phdr), sizeof(pfmt));
+-
+-	phdr.id_RIFF = bswapLE32(phdr.id_RIFF);
+-	phdr.filesize = bswapLE32(phdr.filesize);
+-	phdr.id_WAVE = bswapLE32(phdr.id_WAVE);
+-
+-	pfmt.id_fmt = bswapLE32(pfmt.id_fmt);
+-	pfmt.hdrlen = bswapLE32(pfmt.hdrlen);
+-	pfmt.format = bswapLE16(pfmt.format);
+-	pfmt.channels = bswapLE16(pfmt.channels);
+-	pfmt.freqHz = bswapLE32(pfmt.freqHz);
+-	pfmt.bytessec = bswapLE32(pfmt.bytessec);
+-	pfmt.samplesize = bswapLE16(pfmt.samplesize);
+-	pfmt.bitspersample = bswapLE16(pfmt.bitspersample);
+-
+-	if ((phdr.id_RIFF != IFFID_RIFF) || (phdr.id_WAVE != IFFID_WAVE)
+-	 || (pfmt.id_fmt != IFFID_fmt)) return FALSE;
+-
+-	dwMemPos = sizeof(WAVEFILEHEADER) + 8 + pfmt.hdrlen;
+-
+-	if ((dwMemPos + 8 >= dwMemLength)
+-	 || ((pfmt.format != WAVE_FORMAT_PCM) && (pfmt.format != WAVE_FORMAT_EXTENSIBLE))
+-	 || (pfmt.channels > 4)
+-	 || (!pfmt.channels)
+-	 || (!pfmt.freqHz)
+-	 || (pfmt.bitspersample & 7)
+-	 || (pfmt.bitspersample < 8)
+-	 || (pfmt.bitspersample > 32))  return FALSE;
+-
+-	WAVEDATAHEADER pdata;
+-
+-	for (;;)
+-	{
+-		memcpy(&pdata, lpStream+dwMemPos, sizeof(pdata));
+-		pdata.id_data = bswapLE32(pdata.id_data);
+-		pdata.length = bswapLE32(pdata.length);
+-
+-		if (pdata.id_data == IFFID_data) break;
+-		dwMemPos += pdata.length + 8;
+-		if (dwMemPos + 8 >= dwMemLength) return FALSE;
+-	}
+-	m_nType = MOD_TYPE_WAV;
+-	m_nSamples = 0;
+-	m_nInstruments = 0;
+-	m_nChannels = 4;
+-	m_nDefaultSpeed = 8;
+-	m_nDefaultTempo = 125;
+-	m_dwSongFlags |= SONG_LINEARSLIDES; // For no resampling
+-	Order[0] = 0;
+-	Order[1] = 0xFF;
+-	PatternSize[0] = PatternSize[1] = 64;
+-	PatternAllocSize[0] = PatternAllocSize[1] = 64;
+-	if ((Patterns[0] = AllocatePattern(64, 4)) == NULL) return TRUE;
+-	if ((Patterns[1] = AllocatePattern(64, 4)) == NULL) return TRUE;
+-	UINT samplesize = (pfmt.channels * pfmt.bitspersample) >> 3;
+-	UINT len = pdata.length, bytelen;
+-	if (dwMemPos + len > dwMemLength - 8) len = dwMemLength - dwMemPos - 8;
+-	len /= samplesize;
+-	bytelen = len;
+-	if (pfmt.bitspersample >= 16) bytelen *= 2;
+-	if (len > MAX_SAMPLE_LENGTH) len = MAX_SAMPLE_LENGTH;
+-	if (!len) return TRUE;
+-	// Setting up module length
+-	DWORD dwTime = ((len * 50) / pfmt.freqHz) + 1;
+-	DWORD framesperrow = (dwTime + 63) / 63;
+-	if (framesperrow < 4) framesperrow = 4;
+-	UINT norders = 1;
+-	while (framesperrow >= 0x20)
+-	{
+-		Order[norders++] = 1;
+-		Order[norders] = 0xFF;
+-		framesperrow = (dwTime + (64 * norders - 1)) / (64 * norders);
+-		if (norders >= MAX_ORDERS-1) break;
+-	}
+-	m_nDefaultSpeed = framesperrow;
+-	for (UINT iChn=0; iChn<4; iChn++)
+-	{
+-		ChnSettings[iChn].nPan = (iChn & 1) ? 256 : 0;
+-		ChnSettings[iChn].nVolume = 64;
+-		ChnSettings[iChn].dwFlags = 0;
+-	}
+-	// Setting up speed command
+-	MODCOMMAND *pcmd = Patterns[0];
+-	pcmd[0].command = CMD_SPEED;
+-	pcmd[0].param = (BYTE)m_nDefaultSpeed;
+-	pcmd[0].note = 5*12+1;
+-	pcmd[0].instr = 1;
+-	pcmd[1].note = pcmd[0].note;
+-	pcmd[1].instr = pcmd[0].instr;
+-	m_nSamples = pfmt.channels;
+-	// Support for Multichannel Wave
+-	for (UINT nChn=0; nChn<m_nSamples; nChn++)
+-	{
+-		MODINSTRUMENT *pins = &Ins[nChn+1];
+-		pcmd[nChn].note = pcmd[0].note;
+-		pcmd[nChn].instr = (BYTE)(nChn+1);
+-		pins->nLength = len;
+-		pins->nC4Speed = pfmt.freqHz;
+-		pins->nVolume = 256;
+-		pins->nPan = 128;
+-		pins->nGlobalVol = 64;
+-		pins->uFlags = (WORD)((pfmt.bitspersample >= 16) ? CHN_16BIT : 0);
+-		pins->uFlags |= CHN_PANNING;
+-		if (m_nSamples > 1)
+-		{
+-			switch(nChn)
+-			{
+-			case 0:	pins->nPan = 0; break;
+-			case 1:	pins->nPan = 256; break;
+-			case 2: pins->nPan = (WORD)((m_nSamples == 3) ? 128 : 64); pcmd[nChn].command = CMD_S3MCMDEX; pcmd[nChn].param = 0x91; break;
+-			case 3: pins->nPan = 192; pcmd[nChn].command = CMD_S3MCMDEX; pcmd[nChn].param = 0x91; break;
+-			default: pins->nPan = 128; break;
+-			}
+-		}
+-		if ((pins->pSample = AllocateSample(bytelen+8)) == NULL) return TRUE;
+-		if (pfmt.bitspersample >= 16)
+-		{
+-			int slsize = pfmt.bitspersample >> 3;
+-			signed short *p = (signed short *)pins->pSample;
+-			signed char *psrc = (signed char *)(lpStream+dwMemPos+8+nChn*slsize+slsize-2);
+-			for (UINT i=0; i<len; i++)
+-			{
+-				p[i] = bswapLE16(*((signed short *)psrc));
+-				psrc += samplesize;
+-			}
+-			p[len+1] = p[len] = p[len-1];
+-		} else
+-		{
+-			signed char *p = (signed char *)pins->pSample;
+-			signed char *psrc = (signed char *)(lpStream+dwMemPos+8+nChn);
+-			for (UINT i=0; i<len; i++)
+-			{
+-				p[i] = (signed char)((*psrc) + 0x80);
+-				psrc += samplesize;
+-			}
+-			p[len+1] = p[len] = p[len-1];
+-		}
+-	}
+-	return TRUE;
+-}
+-
+-
+-////////////////////////////////////////////////////////////////////////
+-// IMA ADPCM Support
+-
+-#pragma pack(1)
+-
+-typedef struct IMAADPCMBLOCK
+-{
+-	WORD sample;
+-	BYTE index;
+-	BYTE Reserved;
+-} DVI_ADPCMBLOCKHEADER;
+-
+-#pragma pack()
+-
+-static const int gIMAUnpackTable[90] = 
+-{
+-  7,     8,     9,    10,    11,    12,    13,    14,
+-  16,    17,    19,    21,    23,    25,    28,    31,
+-  34,    37,    41,    45,    50,    55,    60,    66,
+-  73,    80,    88,    97,   107,   118,   130,   143,
+-  157,   173,   190,   209,   230,   253,   279,   307,
+-  337,   371,   408,   449,   494,   544,   598,   658,
+-  724,   796,   876,   963,  1060,  1166,  1282,  1411,
+-  1552,  1707,  1878,  2066,  2272,  2499,  2749,  3024,
+-  3327,  3660,  4026,  4428,  4871,  5358,  5894,  6484,
+-  7132,  7845,  8630,  9493, 10442, 11487, 12635, 13899,
+-  15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
+-  32767, 0
+-};
+-
+-
+-BOOL IMAADPCMUnpack16(signed short *pdest, UINT nLen, LPBYTE psrc, DWORD dwBytes, UINT pkBlkAlign)
+-//------------------------------------------------------------------------------------------------
+-{
+-	static const int gIMAIndexTab[8] =  { -1, -1, -1, -1, 2, 4, 6, 8 };
+-	UINT nPos;
+-	int value;
+-
+-	if ((nLen < 4) || (!pdest) || (!psrc)
+-	 || (pkBlkAlign < 5) || (pkBlkAlign > dwBytes)) return FALSE;
+-	nPos = 0;
+-	while ((nPos < nLen) && (dwBytes > 4))
+-	{
+-		int nIndex;
+-		value = bswapLE16(*((short int *)psrc));
+-		nIndex = bswapLE16((short int)psrc[2]);
+-		psrc += 4;
+-		dwBytes -= 4;
+-		pdest[nPos++] = (short int)value;
+-		for (UINT i=0; ((i<(pkBlkAlign-4)*2) && (nPos < nLen) && (dwBytes)); i++)
+-		{
+-			BYTE delta;
+-			if (i & 1)
+-			{
+-				delta = (BYTE)(((*(psrc++)) >> 4) & 0x0F);
+-				dwBytes--;
+-			} else
+-			{
+-				delta = (BYTE)((*psrc) & 0x0F);
+-			}
+-			int v = gIMAUnpackTable[nIndex % 90] >> 3;
+-			if (delta & 1) v += gIMAUnpackTable[nIndex] >> 2;
+-			if (delta & 2) v += gIMAUnpackTable[nIndex] >> 1;
+-			if (delta & 4) v += gIMAUnpackTable[nIndex];
+-			if (delta & 8) value -= v; else value += v;
+-			nIndex += gIMAIndexTab[delta & 7];
+-			if (nIndex < 0) nIndex = 0; else
+-			if (nIndex > 88) nIndex = 88;
+-			if (value > 32767) value = 32767; else
+-			if (value < -32768) value = -32768;
+-			pdest[nPos++] = (short int)value;
+-		}
+-	}
+-	return TRUE;
+-}
+-
+-
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/load_xm.cxx audacious-plugins-2.5.4/src/modplug/load_xm.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/load_xm.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/load_xm.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,529 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>,
+- *          Adam Goode       <adam at evdebs.org> (endian and char fixes for PPC)
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-////////////////////////////////////////////////////////
+-// FastTracker II XM file support
+-
+-#ifdef MSC_VER
+-#pragma warning(disable:4244)
+-#endif
+-
+-#pragma pack(1)
+-typedef struct tagXMFILEHEADER
+-{
+-	DWORD size;
+-	WORD norder;
+-	WORD restartpos;
+-	WORD channels;
+-	WORD patterns;
+-	WORD instruments;
+-	WORD flags;
+-	WORD speed;
+-	WORD tempo;
+-	BYTE order[256];
+-} XMFILEHEADER;
+-
+-
+-typedef struct tagXMINSTRUMENTHEADER
+-{
+-	DWORD size;
+-	CHAR name[22];
+-	BYTE type;
+-	BYTE samples;
+-	BYTE samplesh;
+-} XMINSTRUMENTHEADER;
+-
+-
+-typedef struct tagXMSAMPLEHEADER
+-{
+-	DWORD shsize;
+-	BYTE snum[96];
+-	WORD venv[24];
+-	WORD penv[24];
+-	BYTE vnum, pnum;
+-	BYTE vsustain, vloops, vloope, psustain, ploops, ploope;
+-	BYTE vtype, ptype;
+-	BYTE vibtype, vibsweep, vibdepth, vibrate;
+-	WORD volfade;
+-	WORD res;
+-	BYTE reserved1[20];
+-} XMSAMPLEHEADER;
+-
+-typedef struct tagXMSAMPLESTRUCT
+-{
+-	DWORD samplen;
+-	DWORD loopstart;
+-	DWORD looplen;
+-	BYTE vol;
+-	signed char finetune;
+-	BYTE type;
+-	BYTE pan;
+-	signed char relnote;
+-	BYTE res;
+-	char name[22];
+-} XMSAMPLESTRUCT;
+-#pragma pack()
+-
+-
+-BOOL CSoundFile::ReadXM(const BYTE *lpStream, DWORD dwMemLength)
+-//--------------------------------------------------------------
+-{
+-	XMSAMPLEHEADER xmsh;
+-	XMSAMPLESTRUCT xmss;
+-	DWORD dwMemPos, dwHdrSize;
+-	WORD norders=0, restartpos=0, channels=0, patterns=0, instruments=0;
+-	WORD xmflags=0, deftempo=125, defspeed=6;
+-	BOOL InstUsed[256];
+-	BYTE channels_used[MAX_CHANNELS];
+-	BYTE pattern_map[256];
+-	BOOL samples_used[MAX_SAMPLES];
+-	UINT unused_samples;
+-
+-	m_nChannels = 0;
+-	if ((!lpStream) || (dwMemLength < 0x200)) return FALSE;
+-	if (strnicmp((LPCSTR)lpStream, "Extended Module", 15)) return FALSE;
+-
+-	memcpy(m_szNames[0], lpStream+17, 20);
+-	dwHdrSize = bswapLE32(*((DWORD *)(lpStream+60)));
+-	norders = bswapLE16(*((WORD *)(lpStream+64)));
+-	if (norders > MAX_ORDERS) return FALSE;
+-	restartpos = bswapLE16(*((WORD *)(lpStream+66)));
+-	channels = bswapLE16(*((WORD *)(lpStream+68)));
+-	if (channels > 64) return FALSE;
+-	m_nType = MOD_TYPE_XM;
+-	m_nMinPeriod = 27;
+-	m_nMaxPeriod = 54784;
+-	m_nChannels = channels;
+-	if (restartpos < norders) m_nRestartPos = restartpos;
+-	patterns = bswapLE16(*((WORD *)(lpStream+70)));
+-	if (patterns > 256) patterns = 256;
+-	instruments = bswapLE16(*((WORD *)(lpStream+72)));
+-	if (instruments >= MAX_INSTRUMENTS) instruments = MAX_INSTRUMENTS-1;
+-	m_nInstruments = instruments;
+-	m_dwSongFlags |= SONG_INSTRUMENTMODE;
+-	m_nSamples = 0;
+-	memcpy(&xmflags, lpStream+74, 2);
+-	xmflags = bswapLE16(xmflags);
+-	if (xmflags & 1) m_dwSongFlags |= SONG_LINEARSLIDES;
+-	if (xmflags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE;
+-	defspeed = bswapLE16(*((WORD *)(lpStream+76)));
+-	deftempo = bswapLE16(*((WORD *)(lpStream+78)));
+-	if ((deftempo >= 32) && (deftempo < 256)) m_nDefaultTempo = deftempo;
+-	if ((defspeed > 0) && (defspeed < 40)) m_nDefaultSpeed = defspeed;
+-	memcpy(Order, lpStream+80, norders);
+-	memset(InstUsed, 0, sizeof(InstUsed));
+-	if (patterns > MAX_PATTERNS)
+-	{
+-		UINT i, j;
+-		for (i=0; i<norders; i++)
+-		{
+-			if (Order[i] < patterns) InstUsed[Order[i]] = TRUE;
+-		}
+-		j = 0;
+-		for (i=0; i<256; i++)
+-		{
+-			if (InstUsed[i]) pattern_map[i] = j++;
+-		}
+-		for (i=0; i<256; i++)
+-		{
+-			if (!InstUsed[i])
+-			{
+-				pattern_map[i] = (j < MAX_PATTERNS) ? j : 0xFE;
+-				j++;
+-			}
+-		}
+-		for (i=0; i<norders; i++)
+-		{
+-			Order[i] = pattern_map[Order[i]];
+-		}
+-	} else
+-	{
+-		for (UINT i=0; i<256; i++) pattern_map[i] = i;
+-	}
+-	memset(InstUsed, 0, sizeof(InstUsed));
+-	dwMemPos = dwHdrSize + 60;
+-	if (dwMemPos + 8 >= dwMemLength) return TRUE;
+-	// Reading patterns
+-	memset(channels_used, 0, sizeof(channels_used));
+-	for (UINT ipat=0; ipat<patterns; ipat++)
+-	{
+-		UINT ipatmap = pattern_map[ipat];
+-		DWORD dwSize = 0;
+-		WORD rows=64, packsize=0;
+-		dwSize = bswapLE32(*((DWORD *)(lpStream+dwMemPos)));
+-		while ((dwMemPos + dwSize >= dwMemLength) || (dwSize & 0xFFFFFF00))
+-		{
+-			if (dwMemPos + 4 >= dwMemLength) break;
+-			dwMemPos++;
+-			dwSize = bswapLE32(*((DWORD *)(lpStream+dwMemPos)));
+-		}
+-		rows = bswapLE16(*((WORD *)(lpStream+dwMemPos+5)));
+-		if ((!rows) || (rows > 256)) rows = 64;
+-		packsize = bswapLE16(*((WORD *)(lpStream+dwMemPos+7)));
+-		if (dwMemPos + dwSize + 4 > dwMemLength) return TRUE;
+-		dwMemPos += dwSize;
+-		if (dwMemPos + packsize + 4 > dwMemLength) return TRUE;
+-		MODCOMMAND *p;
+-		if (ipatmap < MAX_PATTERNS)
+-		{
+-			PatternSize[ipatmap] = rows;
+-			PatternAllocSize[ipatmap] = rows;
+-			if ((Patterns[ipatmap] = AllocatePattern(rows, m_nChannels)) == NULL) return TRUE;
+-			if (!packsize) continue;
+-			p = Patterns[ipatmap];
+-		} else p = NULL;
+-		const BYTE *src = lpStream+dwMemPos;
+-		UINT j=0;
+-		for (UINT row=0; row<rows; row++)
+-		{
+-			for (UINT chn=0; chn<m_nChannels; chn++)
+-			{
+-				if ((p) && (j < packsize))
+-				{
+-					BYTE b = src[j++];
+-					UINT vol = 0;
+-					if (b & 0x80)
+-					{
+-						if (b & 1) p->note = src[j++];
+-						if (b & 2) p->instr = src[j++];
+-						if (b & 4) vol = src[j++];
+-						if (b & 8) p->command = src[j++];
+-						if (b & 16) p->param = src[j++];
+-					} else
+-					{
+-						p->note = b;
+-						p->instr = src[j++];
+-						vol = src[j++];
+-						p->command = src[j++];
+-						p->param = src[j++];
+-					}
+-					if (p->note == 97) p->note = 0xFF; else
+-					if ((p->note) && (p->note < 97)) p->note += 12;
+-					if (p->note) channels_used[chn] = 1;
+-					if (p->command | p->param) ConvertModCommand(p);
+-					if (p->instr == 0xff) p->instr = 0;
+-					if (p->instr) InstUsed[p->instr] = TRUE;
+-					if ((vol >= 0x10) && (vol <= 0x50))
+-					{
+-						p->volcmd = VOLCMD_VOLUME;
+-						p->vol = vol - 0x10;
+-					} else
+-					if (vol >= 0x60)
+-					{
+-						UINT v = vol & 0xF0;
+-						vol &= 0x0F;
+-						p->vol = vol;
+-						switch(v)
+-						{
+-						// 60-6F: Volume Slide Down
+-						case 0x60:	p->volcmd = VOLCMD_VOLSLIDEDOWN; break;
+-						// 70-7F: Volume Slide Up:
+-						case 0x70:	p->volcmd = VOLCMD_VOLSLIDEUP; break;
+-						// 80-8F: Fine Volume Slide Down
+-						case 0x80:	p->volcmd = VOLCMD_FINEVOLDOWN; break;
+-						// 90-9F: Fine Volume Slide Up
+-						case 0x90:	p->volcmd = VOLCMD_FINEVOLUP; break;
+-						// A0-AF: Set Vibrato Speed
+-						case 0xA0:	p->volcmd = VOLCMD_VIBRATOSPEED; break;
+-						// B0-BF: Vibrato
+-						case 0xB0:	p->volcmd = VOLCMD_VIBRATO; break;
+-						// C0-CF: Set Panning
+-						case 0xC0:	p->volcmd = VOLCMD_PANNING; p->vol = (vol << 2) + 2; break;
+-						// D0-DF: Panning Slide Left
+-						case 0xD0:	p->volcmd = VOLCMD_PANSLIDELEFT; break;
+-						// E0-EF: Panning Slide Right
+-						case 0xE0:	p->volcmd = VOLCMD_PANSLIDERIGHT; break;
+-						// F0-FF: Tone Portamento
+-						case 0xF0:	p->volcmd = VOLCMD_TONEPORTAMENTO; break;
+-						}
+-					}
+-					p++;
+-				} else
+-				if (j < packsize)
+-				{
+-					BYTE b = src[j++];
+-					if (b & 0x80)
+-					{
+-						if (b & 1) j++;
+-						if (b & 2) j++;
+-						if (b & 4) j++;
+-						if (b & 8) j++;
+-						if (b & 16) j++;
+-					} else j += 4;
+-				} else break;
+-			}
+-		}
+-		dwMemPos += packsize;
+-	}
+-	// Wrong offset check
+-	while (dwMemPos + 4 < dwMemLength)
+-	{
+-		DWORD d = bswapLE32(*((DWORD *)(lpStream+dwMemPos)));
+-		if (d < 0x300) break;
+-		dwMemPos++;
+-	}
+-	memset(samples_used, 0, sizeof(samples_used));
+-	unused_samples = 0;
+-	// Reading instruments
+-	for (UINT iIns=1; iIns<=instruments; iIns++)
+-	{
+-		XMINSTRUMENTHEADER *pih;
+-		BYTE flags[32];
+-		DWORD samplesize[32];
+-		UINT samplemap[32];
+-		WORD nsamples;
+-
+-		if (dwMemPos + sizeof(XMINSTRUMENTHEADER) >= dwMemLength) return TRUE;
+-		pih = (XMINSTRUMENTHEADER *)(lpStream+dwMemPos);
+-		if (dwMemPos + bswapLE32(pih->size) > dwMemLength) return TRUE;
+-		if ((Headers[iIns] = new INSTRUMENTHEADER) == NULL) continue;
+-		memset(Headers[iIns], 0, sizeof(INSTRUMENTHEADER));
+-		memcpy(Headers[iIns]->name, pih->name, 22);
+-		if ((nsamples = pih->samples) > 0)
+-		{
+-			if (dwMemPos + sizeof(XMSAMPLEHEADER) > dwMemLength) return TRUE;
+-			memcpy(&xmsh, lpStream+dwMemPos+sizeof(XMINSTRUMENTHEADER), sizeof(XMSAMPLEHEADER));
+-			xmsh.shsize = bswapLE32(xmsh.shsize);
+-			for (int i = 0; i < 24; ++i) {
+-			  xmsh.venv[i] = bswapLE16(xmsh.venv[i]);
+-			  xmsh.penv[i] = bswapLE16(xmsh.penv[i]);
+-			}
+-			xmsh.volfade = bswapLE16(xmsh.volfade);
+-			xmsh.res = bswapLE16(xmsh.res);
+-			dwMemPos += bswapLE32(pih->size);
+-		} else
+-		{
+-			if (bswapLE32(pih->size)) dwMemPos += bswapLE32(pih->size);
+-			else dwMemPos += sizeof(XMINSTRUMENTHEADER);
+-			continue;
+-		}
+-		memset(samplemap, 0, sizeof(samplemap));
+-		if (nsamples > 32) return TRUE;
+-		UINT newsamples = m_nSamples;
+-		for (UINT nmap=0; nmap<nsamples; nmap++)
+-		{
+-			UINT n = m_nSamples+nmap+1;
+-			if (n >= MAX_SAMPLES)
+-			{
+-				n = m_nSamples;
+-				while (n > 0)
+-				{
+-					if (!Ins[n].pSample)
+-					{
+-						for (UINT xmapchk=0; xmapchk < nmap; xmapchk++)
+-						{
+-							if (samplemap[xmapchk] == n) goto alreadymapped;
+-						}
+-						for (UINT clrs=1; clrs<iIns; clrs++) if (Headers[clrs])
+-						{
+-							INSTRUMENTHEADER *pks = Headers[clrs];
+-							for (UINT ks=0; ks<128; ks++)
+-							{
+-								if (pks->Keyboard[ks] == n) pks->Keyboard[ks] = 0;
+-							}
+-						}
+-						break;
+-					}
+-				alreadymapped:
+-					n--;
+-				}
+-#ifndef MODPLUG_FASTSOUNDLIB
+-				// Damn! more than 200 samples: look for duplicates
+-				if (!n)
+-				{
+-					if (!unused_samples)
+-					{
+-						unused_samples = DetectUnusedSamples(samples_used);
+-						if (!unused_samples) unused_samples = 0xFFFF;
+-					}
+-					if ((unused_samples) && (unused_samples != 0xFFFF))
+-					{
+-						for (UINT iext=m_nSamples; iext>=1; iext--) if (!samples_used[iext])
+-						{
+-							unused_samples--;
+-							samples_used[iext] = TRUE;
+-							DestroySample(iext);
+-							n = iext;
+-							for (UINT mapchk=0; mapchk<nmap; mapchk++)
+-							{
+-								if (samplemap[mapchk] == n) samplemap[mapchk] = 0;
+-							}
+-							for (UINT clrs=1; clrs<iIns; clrs++) if (Headers[clrs])
+-							{
+-								INSTRUMENTHEADER *pks = Headers[clrs];
+-								for (UINT ks=0; ks<128; ks++)
+-								{
+-									if (pks->Keyboard[ks] == n) pks->Keyboard[ks] = 0;
+-								}
+-							}
+-							memset(&Ins[n], 0, sizeof(Ins[0]));
+-							break;
+-						}
+-					}
+-				}
+-#endif // MODPLUG_FASTSOUNDLIB
+-			}
+-			if (newsamples < n) newsamples = n;
+-			samplemap[nmap] = n;
+-		}
+-		m_nSamples = newsamples;
+-		// Reading Volume Envelope
+-		INSTRUMENTHEADER *penv = Headers[iIns];
+-		penv->nMidiProgram = pih->type;
+-		penv->nFadeOut = xmsh.volfade;
+-		penv->nPan = 128;
+-		penv->nPPC = 5*12;
+-		if (xmsh.vtype & 1) penv->dwFlags |= ENV_VOLUME;
+-		if (xmsh.vtype & 2) penv->dwFlags |= ENV_VOLSUSTAIN;
+-		if (xmsh.vtype & 4) penv->dwFlags |= ENV_VOLLOOP;
+-		if (xmsh.ptype & 1) penv->dwFlags |= ENV_PANNING;
+-		if (xmsh.ptype & 2) penv->dwFlags |= ENV_PANSUSTAIN;
+-		if (xmsh.ptype & 4) penv->dwFlags |= ENV_PANLOOP;
+-		if (xmsh.vnum > 12) xmsh.vnum = 12;
+-		if (xmsh.pnum > 12) xmsh.pnum = 12;
+-		penv->VolEnv.nNodes = xmsh.vnum;
+-		if (!xmsh.vnum) penv->dwFlags &= ~ENV_VOLUME;
+-		if (!xmsh.pnum) penv->dwFlags &= ~ENV_PANNING;
+-		if (!(penv->dwFlags & ENV_VOLUME) && !penv->nFadeOut) {
+-			penv->nFadeOut = 8192;
+-		}
+-		penv->PanEnv.nNodes = xmsh.pnum;
+-		penv->VolEnv.nSustainStart = penv->VolEnv.nSustainEnd = xmsh.vsustain;
+-		if (xmsh.vsustain >= 12) penv->dwFlags &= ~ENV_VOLSUSTAIN;
+-		penv->VolEnv.nLoopStart = xmsh.vloops;
+-		penv->VolEnv.nLoopEnd = xmsh.vloope;
+-		if (penv->VolEnv.nLoopEnd >= 12) penv->VolEnv.nLoopEnd = 0;
+-		if (penv->VolEnv.nLoopStart >= penv->VolEnv.nLoopEnd) penv->dwFlags &= ~ENV_VOLLOOP;
+-		penv->PanEnv.nSustainStart = penv->PanEnv.nSustainEnd = xmsh.psustain;
+-		if (xmsh.psustain >= 12) penv->dwFlags &= ~ENV_PANSUSTAIN;
+-		penv->PanEnv.nLoopStart = xmsh.ploops;
+-		penv->PanEnv.nLoopEnd = xmsh.ploope;
+-		if (penv->PanEnv.nLoopEnd >= 12) penv->PanEnv.nLoopEnd = 0;
+-		if (penv->PanEnv.nLoopStart >= penv->PanEnv.nLoopEnd) penv->dwFlags &= ~ENV_PANLOOP;
+-		penv->nGlobalVol = 128;
+-		for (UINT ienv=0; ienv<12; ienv++)
+-		{
+-			penv->VolEnv.Ticks[ienv] = (WORD)xmsh.venv[ienv*2];
+-			penv->VolEnv.Values[ienv] = (BYTE)xmsh.venv[ienv*2+1];
+-			penv->PanEnv.Ticks[ienv] = (WORD)xmsh.penv[ienv*2];
+-			penv->PanEnv.Values[ienv] = (BYTE)xmsh.penv[ienv*2+1];
+-			if (ienv)
+-			{
+-				if (penv->VolEnv.Ticks[ienv] < penv->VolEnv.Ticks[ienv-1])
+-				{
+-					penv->VolEnv.Ticks[ienv] &= 0xFF;
+-					penv->VolEnv.Ticks[ienv] += penv->VolEnv.Ticks[ienv-1] & 0xFF00;
+-					if (penv->VolEnv.Ticks[ienv] < penv->VolEnv.Ticks[ienv-1]) penv->VolEnv.Ticks[ienv] += 0x100;
+-				}
+-				if (penv->PanEnv.Ticks[ienv] < penv->PanEnv.Ticks[ienv-1])
+-				{
+-					penv->PanEnv.Ticks[ienv] &= 0xFF;
+-					penv->PanEnv.Ticks[ienv] += penv->PanEnv.Ticks[ienv-1] & 0xFF00;
+-					if (penv->PanEnv.Ticks[ienv] < penv->PanEnv.Ticks[ienv-1]) penv->PanEnv.Ticks[ienv] += 0x100;
+-				}
+-			}
+-		}
+-		for (UINT j=0; j<96; j++)
+-		{
+-			penv->NoteMap[j+12] = j+1+12;
+-			if (xmsh.snum[j] < nsamples)
+-				penv->Keyboard[j+12] = samplemap[xmsh.snum[j]];
+-		}
+-		// Reading samples
+-		for (UINT ins=0; ins<nsamples; ins++)
+-		{
+-			if ((dwMemPos + sizeof(xmss) > dwMemLength)
+-			 || (dwMemPos + xmsh.shsize > dwMemLength)) return TRUE;
+-			memcpy(&xmss, lpStream+dwMemPos, sizeof(xmss));
+-			xmss.samplen = bswapLE32(xmss.samplen);
+-			xmss.loopstart = bswapLE32(xmss.loopstart);
+-			xmss.looplen = bswapLE32(xmss.looplen);
+-			dwMemPos += xmsh.shsize;
+-			flags[ins] = (xmss.type & 0x10) ? RS_PCM16D : RS_PCM8D;
+-			if (xmss.type & 0x20) flags[ins] = (xmss.type & 0x10) ? RS_STPCM16D : RS_STPCM8D;
+-			samplesize[ins] = xmss.samplen;
+-			if (!samplemap[ins]) continue;
+-			if (xmss.type & 0x10)
+-			{
+-				xmss.looplen >>= 1;
+-				xmss.loopstart >>= 1;
+-				xmss.samplen >>= 1;
+-			}
+-			if (xmss.type & 0x20)
+-			{
+-				xmss.looplen >>= 1;
+-				xmss.loopstart >>= 1;
+-				xmss.samplen >>= 1;
+-			}
+-			if (xmss.samplen > MAX_SAMPLE_LENGTH) xmss.samplen = MAX_SAMPLE_LENGTH;
+-			if (xmss.loopstart >= xmss.samplen) xmss.type &= ~3;
+-			xmss.looplen += xmss.loopstart;
+-			if (xmss.looplen > xmss.samplen) xmss.looplen = xmss.samplen;
+-			if (!xmss.looplen) xmss.type &= ~3;
+-			UINT imapsmp = samplemap[ins];
+-			memcpy(m_szNames[imapsmp], xmss.name, 22);
+-			m_szNames[imapsmp][22] = 0;
+-			MODINSTRUMENT *pins = &Ins[imapsmp];
+-			pins->nLength = (xmss.samplen > MAX_SAMPLE_LENGTH) ? MAX_SAMPLE_LENGTH : xmss.samplen;
+-			pins->nLoopStart = xmss.loopstart;
+-			pins->nLoopEnd = xmss.looplen;
+-			if (pins->nLoopEnd > pins->nLength) pins->nLoopEnd = pins->nLength;
+-			if (pins->nLoopStart >= pins->nLoopEnd)
+-			{
+-				pins->nLoopStart = pins->nLoopEnd = 0;
+-			}
+-			if (xmss.type & 3) pins->uFlags |= CHN_LOOP;
+-			if (xmss.type & 2) pins->uFlags |= CHN_PINGPONGLOOP;
+-			pins->nVolume = xmss.vol << 2;
+-			if (pins->nVolume > 256) pins->nVolume = 256;
+-			pins->nGlobalVol = 64;
+-			if ((xmss.res == 0xAD) && (!(xmss.type & 0x30)))
+-			{
+-				flags[ins] = RS_ADPCM4;
+-				samplesize[ins] = (samplesize[ins]+1)/2 + 16;
+-			}
+-			pins->nFineTune = xmss.finetune;
+-			pins->RelativeTone = (int)xmss.relnote;
+-			pins->nPan = xmss.pan;
+-			pins->uFlags |= CHN_PANNING;
+-			pins->nVibType = xmsh.vibtype;
+-			pins->nVibSweep = xmsh.vibsweep;
+-			pins->nVibDepth = xmsh.vibdepth;
+-			pins->nVibRate = xmsh.vibrate/4;
+-			memcpy(pins->name, xmss.name, 22);
+-			pins->name[21] = 0;
+-		}
+-#if 0
+-		if ((xmsh.reserved2 > nsamples) && (xmsh.reserved2 <= 16))
+-		{
+-			dwMemPos += (((UINT)xmsh.reserved2) - nsamples) * xmsh.shsize;
+-		}
+-#endif
+-		for (UINT ismpd=0; ismpd<nsamples; ismpd++)
+-		{
+-			if ((samplemap[ismpd]) && (samplesize[ismpd]) && (dwMemPos < dwMemLength))
+-			{
+-				ReadSample(&Ins[samplemap[ismpd]], flags[ismpd], (LPSTR)(lpStream + dwMemPos), dwMemLength - dwMemPos);
+-			}
+-			dwMemPos += samplesize[ismpd];
+-			if (dwMemPos >= dwMemLength) break;
+-		}
+-	}
+-	/* set these to default */
+-	for (UINT in=0; in<m_nChannels; in++)
+-	{
+-		ChnSettings[in].nVolume = 64;
+-		ChnSettings[in].nPan = 128;
+-		ChnSettings[in].dwFlags = 0;
+-	}
+-	return TRUE;
+-}
+-
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/Makefile audacious-plugins-2.5.4/src/modplug/Makefile
+--- audacious-plugins-2.5.4-orig/src/modplug/Makefile	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/Makefile	2011-09-08 18:41:48.800906287 +0200
+@@ -2,37 +2,6 @@
+ 
+ SRCS = plugin.cxx		\
+        modplugbmp.cxx		\
+-       tables.cxx		\
+-       sndmix.cxx		\
+-       sndfile.cxx		\
+-       snd_eq.cxx		\
+-       snd_fx.cxx		\
+-       snd_flt.cxx		\
+-       snd_dsp.cxx		\
+-       fastmix.cxx		\
+-       mmcmp.cxx		\
+-       load_xm.cxx		\
+-       load_wav.cxx		\
+-       load_umx.cxx		\
+-       load_ult.cxx		\
+-       load_stm.cxx		\
+-       load_s3m.cxx		\
+-       load_ptm.cxx		\
+-       load_okt.cxx		\
+-       load_mtm.cxx		\
+-       load_mod.cxx		\
+-       load_med.cxx		\
+-       load_mdl.cxx		\
+-       load_it.cxx		\
+-       load_far.cxx		\
+-       load_dsm.cxx		\
+-       load_dmf.cxx		\
+-       load_dbm.cxx		\
+-       load_ams.cxx		\
+-       load_amf.cxx		\
+-       load_669.cxx		\
+-       load_mt2.cxx		\
+-       load_psm.cxx		\
+        archive/archive.cxx	\
+        archive/open.cxx		\
+        archive/arch_raw.cxx	\
+@@ -50,5 +19,5 @@
+ LD = ${CXX}
+ CFLAGS += ${PLUGIN_CFLAGS}
+ CXXFLAGS += ${PLUGIN_CFLAGS}
+-CPPFLAGS += ${PLUGIN_CPPFLAGS} ${MOWGLI_CFLAGS}  ${GTK_CFLAGS} ${GLIB_CFLAGS}  -I.. -I../.. -I../../intl
+-LIBS += ${MOWGLI_LIBS}  ${GTK_LIBS} ${GLIB_LIBS}  -lstdc++
++CPPFLAGS += ${PLUGIN_CPPFLAGS} ${MOWGLI_CFLAGS}  ${GTK_CFLAGS} ${GLIB_CFLAGS}  -I.. -I../.. -I../../intl -I/usr/include/libmodplug
++LIBS += ${MOWGLI_LIBS}  ${GTK_LIBS} ${GLIB_LIBS}  -lstdc++ -lmodplug
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/midi.h audacious-plugins-2.5.4/src/modplug/midi.h
+--- audacious-plugins-2.5.4-orig/src/modplug/midi.h	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/midi.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,185 +0,0 @@
+-/*
+- * Schism Tracker - a cross-platform Impulse Tracker clone
+- * copyright (c) 2003-2005 chisel <schism at chisel.cjb.net>
+- * copyright (c) 2005-2006 Mrs. Brisby <mrs.brisby at nimh.org>
+- * URL: http://nimh.org/schism/
+- * URL: http://rigelseven.com/schism/
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+- */
+-
+-#ifndef MIDI_H
+-#define MIDI_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-struct midi_provider;
+-struct midi_port;
+-
+-struct midi_driver {
+-	unsigned int flags;
+-#define MIDI_PORT_CAN_SCHEDULE	1
+-
+-	void (*poll)(struct midi_provider *m);
+-	int (*thread)(struct midi_provider *m);
+-
+-	int (*enable)(struct midi_port *d);
+-	int (*disable)(struct midi_port *d);
+-
+-	void (*send)(struct midi_port *d,
+-			unsigned char *seq, unsigned int len, unsigned int delay);
+-	void (*drain)(struct midi_port *d);
+-};
+-
+-struct midi_provider {
+-	const char *name;
+-	void (*poll)(struct midi_provider *);
+-	void *thread; /*actually SDL_Thread* */
+-
+-	struct midi_provider *next;
+-
+-	/* forwarded; don't touch */
+-	int (*enable)(struct midi_port *d);
+-	int (*disable)(struct midi_port *d);
+-
+-	void (*send_now)(struct midi_port *d,
+-			unsigned char *seq, unsigned int len, unsigned int delay);
+-	void (*send_later)(struct midi_port *d,
+-			unsigned char *seq, unsigned int len, unsigned int delay);
+-	void (*drain)(struct midi_port *d);
+-};
+-struct midi_port {
+-	int io, iocap;
+-#define MIDI_INPUT	1
+-#define MIDI_OUTPUT	2
+-	char *name;
+-	int num;
+-
+-	void *userdata;
+-	int free_userdata;
+-	int (*enable)(struct midi_port *d);
+-	int (*disable)(struct midi_port *d);
+-	void (*send_now)(struct midi_port *d,
+-			unsigned char *seq, unsigned int len, unsigned int delay);
+-	void (*send_later)(struct midi_port *d,
+-			unsigned char *seq, unsigned int len, unsigned int delay);
+-	void (*drain)(struct midi_port *d);
+-
+-	struct midi_provider *provider;
+-};
+-
+-
+-/* schism calls these directly */
+-int midi_engine_start(void);
+-void midi_engine_reset(void);
+-void midi_engine_stop(void);
+-void midi_engine_poll_ports(void);
+-
+-/* some parts of schism call this; it means "immediately" */
+-void midi_send_now(unsigned char *seq, unsigned int len);
+-
+-/* ... but the player calls this */
+-void midi_send_buffer(unsigned char *data, unsigned int len, unsigned int pos);
+-void midi_send_flush(void);
+-
+-/* from the SDL event mechanism (x is really SDL_Event) */
+-int midi_engine_handle_event(void *x);
+-
+-struct midi_port *midi_engine_port(int n, const char **name);
+-int midi_engine_port_count(void);
+-
+-/* midi engines register a provider (one each!) */
+-struct midi_provider *midi_provider_register(const char *name, struct midi_driver *f);
+-		
+-
+-/* midi engines list ports this way */
+-int midi_port_register(struct midi_provider *p,
+-int inout, const char *name, void *userdata, int free_userdata);
+-
+-int midi_port_foreach(struct midi_provider *p, struct midi_port **cursor);
+-void midi_port_unregister(int num);
+-
+-/* only call these if the event isn't really MIDI but you want most of the system
+-   to act like it is...
+-
+-   midi drivers should never all these...
+-*/
+-enum midi_note {
+-	MIDI_NOTEOFF,
+-	MIDI_NOTEON,
+-	MIDI_KEYPRESS,
+-};
+-void midi_event_note(enum midi_note mnstatus, int channel, int note, int velocity);
+-void midi_event_controller(int channel, int param, int value);
+-void midi_event_program(int channel, int value);
+-void midi_event_aftertouch(int channel, int value);
+-void midi_event_pitchbend(int channel, int value);
+-void midi_event_tick(void);
+-void midi_event_sysex(const unsigned char *data, unsigned int len);
+-void midi_event_system(int argv, int param);
+-
+-/* midi drivers call this when they received an event */
+-void midi_received_cb(struct midi_port *src, unsigned char *data, unsigned int len);
+-
+-
+-#ifdef USE_NETWORK
+-int ip_midi_setup(void);
+-#endif
+-#ifdef USE_OSS
+-int oss_midi_setup(void);
+-#endif
+-#ifdef USE_ALSA
+-int alsa_midi_setup(void);
+-#endif
+-#ifdef USE_WIN32MM
+-int win32mm_midi_setup(void);
+-#endif
+-#ifdef MACOSX
+-int macosx_midi_setup(void);
+-#endif
+-
+-
+-
+-#define MIDI_TICK_QUANTIZE	0x00000001
+-#define MIDI_BASE_PROGRAM1	0x00000002
+-#define MIDI_RECORD_NOTEOFF	0x00000004
+-#define MIDI_RECORD_VELOCITY	0x00000008
+-#define MIDI_RECORD_AFTERTOUCH	0x00000010
+-#define MIDI_CUT_NOTE_OFF	0x00000020
+-#define MIDI_PITCH_BEND		0x00000040
+-#define MIDI_EMBED_DATA		0x00000080
+-#define MIDI_RECORD_SDX		0x00000100
+-#define MIDI_DISABLE_RECORD	0x00010000
+-
+-/* configurable midi stuff */
+-int midi_flags = MIDI_TICK_QUANTIZE | MIDI_RECORD_NOTEOFF
+-                | MIDI_RECORD_VELOCITY | MIDI_RECORD_AFTERTOUCH
+-                | MIDI_PITCH_BEND;
+-
+-int midi_pitch_depth = 12;
+-int midi_amplification = 100;
+-int midi_c5note = 60;
+-
+-/* only available with networks */
+-void ip_midi_setports(int n);
+-int ip_midi_getports(void);
+-
+-#ifdef __cplusplus
+-};
+-#endif
+-
+-#endif
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/mmcmp.cxx audacious-plugins-2.5.4/src/modplug/mmcmp.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/mmcmp.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/mmcmp.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,406 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-BOOL PP20_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength);
+-
+-typedef struct MMCMPFILEHEADER
+-{
+-	DWORD id_ziRC;	// "ziRC"
+-	DWORD id_ONia;	// "ONia"
+-	WORD hdrsize;
+-} MMCMPFILEHEADER, *LPMMCMPFILEHEADER;
+-
+-typedef struct MMCMPHEADER
+-{
+-	WORD version;
+-	WORD nblocks;
+-	DWORD filesize;
+-	DWORD blktable;
+-	BYTE glb_comp;
+-	BYTE fmt_comp;
+-} MMCMPHEADER, *LPMMCMPHEADER;
+-
+-typedef struct MMCMPBLOCK
+-{
+-	DWORD unpk_size;
+-	DWORD pk_size;
+-	DWORD xor_chk;
+-	WORD sub_blk;
+-	WORD flags;
+-	WORD tt_entries;
+-	WORD num_bits;
+-} MMCMPBLOCK, *LPMMCMPBLOCK;
+-
+-typedef struct MMCMPSUBBLOCK
+-{
+-	DWORD unpk_pos;
+-	DWORD unpk_size;
+-} MMCMPSUBBLOCK, *LPMMCMPSUBBLOCK;
+-
+-#define MMCMP_COMP		0x0001
+-#define MMCMP_DELTA		0x0002
+-#define MMCMP_16BIT		0x0004
+-#define MMCMP_STEREO	0x0100
+-#define MMCMP_ABS16		0x0200
+-#define MMCMP_ENDIAN	0x0400
+-
+-typedef struct MMCMPBITBUFFER
+-{
+-	UINT bitcount;
+-	DWORD bitbuffer;
+-	LPCBYTE pSrc;
+-	LPCBYTE pEnd;
+-
+-	DWORD GetBits(UINT nBits);
+-} MMCMPBITBUFFER;
+-
+-
+-DWORD MMCMPBITBUFFER::GetBits(UINT nBits)
+-//---------------------------------------
+-{
+-	DWORD d;
+-	if (!nBits) return 0;
+-	while (bitcount < 24)
+-	{
+-		bitbuffer |= ((pSrc < pEnd) ? *pSrc++ : 0) << bitcount;
+-		bitcount += 8;
+-	}
+-	d = bitbuffer & ((1 << nBits) - 1);
+-	bitbuffer >>= nBits;
+-	bitcount -= nBits;
+-	return d;
+-}
+-
+-//#define MMCMP_LOG
+-
+-#ifdef MMCMP_LOG
+-extern void Log(LPCSTR s, ...);
+-#endif
+-
+-const DWORD MMCMP8BitCommands[8] =
+-{
+-	0x01, 0x03,	0x07, 0x0F,	0x1E, 0x3C,	0x78, 0xF8
+-};
+-
+-const UINT MMCMP8BitFetch[8] =
+-{
+-	3, 3, 3, 3, 2, 1, 0, 0
+-};
+-
+-const DWORD MMCMP16BitCommands[16] =
+-{
+-	0x01, 0x03,	0x07, 0x0F,	0x1E, 0x3C,	0x78, 0xF0,
+-	0x1F0, 0x3F0, 0x7F0, 0xFF0, 0x1FF0, 0x3FF0, 0x7FF0, 0xFFF0
+-};
+-
+-const UINT MMCMP16BitFetch[16] =
+-{
+-	4, 4, 4, 4, 3, 2, 1, 0,
+-	0, 0, 0, 0, 0, 0, 0, 0
+-};
+-
+-
+-BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength)
+-//---------------------------------------------------------
+-{
+-	DWORD dwMemLength = *pdwMemLength;
+-	LPCBYTE lpMemFile = *ppMemFile;
+-	LPBYTE pBuffer;
+-	LPMMCMPFILEHEADER pmfh = (LPMMCMPFILEHEADER)(lpMemFile);
+-	LPMMCMPHEADER pmmh = (LPMMCMPHEADER)(lpMemFile+10);
+-	LPDWORD pblk_table;
+-	DWORD dwFileSize;
+-
+-	if (PP20_Unpack(ppMemFile, pdwMemLength))
+-	{
+-		return TRUE;
+-	}
+-	if ((dwMemLength < 256) || (!pmfh) || (pmfh->id_ziRC != 0x4352697A) || (pmfh->id_ONia != 0x61694e4f) || (pmfh->hdrsize < 14)
+-	 || (!pmmh->nblocks) || (pmmh->filesize < 16) || (pmmh->filesize > 0x8000000)
+-	 || (pmmh->blktable >= dwMemLength) || (pmmh->blktable + 4*pmmh->nblocks > dwMemLength)) return FALSE;
+-	dwFileSize = pmmh->filesize;
+-	if ((pBuffer = (LPBYTE)GlobalAllocPtr(GHND, (dwFileSize + 31) & ~15)) == NULL) return FALSE;
+-	pblk_table = (LPDWORD)(lpMemFile+pmmh->blktable);
+-	for (UINT nBlock=0; nBlock<pmmh->nblocks; nBlock++)
+-	{
+-		DWORD dwMemPos = pblk_table[nBlock];
+-		LPMMCMPBLOCK pblk = (LPMMCMPBLOCK)(lpMemFile+dwMemPos);
+-		LPMMCMPSUBBLOCK psubblk = (LPMMCMPSUBBLOCK)(lpMemFile+dwMemPos+20);
+-
+-		if ((dwMemPos + 20 >= dwMemLength) || (dwMemPos + 20 + pblk->sub_blk*8 >= dwMemLength)) break;
+-		dwMemPos += 20 + pblk->sub_blk*8;
+-#ifdef MMCMP_LOG
+-		Log("block %d: flags=%04X sub_blocks=%d", nBlock, (UINT)pblk->flags, (UINT)pblk->sub_blk);
+-		Log(" pksize=%d unpksize=%d", pblk->pk_size, pblk->unpk_size);
+-		Log(" tt_entries=%d num_bits=%d\n", pblk->tt_entries, pblk->num_bits);
+-#endif
+-		// Data is not packed
+-		if (!(pblk->flags & MMCMP_COMP))
+-		{
+-			for (UINT i=0; i<pblk->sub_blk; i++)
+-			{
+-				if ((psubblk->unpk_pos > dwFileSize) || (psubblk->unpk_pos + psubblk->unpk_size > dwFileSize)) break;
+-#ifdef MMCMP_LOG
+-				Log("  Unpacked sub-block %d: offset %d, size=%d\n", i, psubblk->unpk_pos, psubblk->unpk_size);
+-#endif
+-				memcpy(pBuffer+psubblk->unpk_pos, lpMemFile+dwMemPos, psubblk->unpk_size);
+-				dwMemPos += psubblk->unpk_size;
+-				psubblk++;
+-			}
+-		} else
+-		// Data is 16-bit packed
+-		if (pblk->flags & MMCMP_16BIT)
+-		{
+-			MMCMPBITBUFFER bb;
+-			LPWORD pDest = (LPWORD)(pBuffer + psubblk->unpk_pos);
+-			DWORD dwSize = psubblk->unpk_size >> 1;
+-			DWORD dwPos = 0;
+-			UINT numbits = pblk->num_bits;
+-			UINT subblk = 0, oldval = 0;
+-
+-#ifdef MMCMP_LOG
+-			Log("  16-bit block: pos=%d size=%d ", psubblk->unpk_pos, psubblk->unpk_size);
+-			if (pblk->flags & MMCMP_DELTA) Log("DELTA ");
+-			if (pblk->flags & MMCMP_ABS16) Log("ABS16 ");
+-			Log("\n");
+-#endif
+-			bb.bitcount = 0;
+-			bb.bitbuffer = 0;
+-			bb.pSrc = lpMemFile+dwMemPos+pblk->tt_entries;
+-			bb.pEnd = lpMemFile+dwMemPos+pblk->pk_size;
+-			while (subblk < pblk->sub_blk)
+-			{
+-				UINT newval = 0x10000;
+-				DWORD d = bb.GetBits(numbits+1);
+-
+-				if (d >= MMCMP16BitCommands[numbits])
+-				{
+-					UINT nFetch = MMCMP16BitFetch[numbits];
+-					UINT newbits = bb.GetBits(nFetch) + ((d - MMCMP16BitCommands[numbits]) << nFetch);
+-					if (newbits != numbits)
+-					{
+-						numbits = newbits & 0x0F;
+-					} else
+-					{
+-						if ((d = bb.GetBits(4)) == 0x0F)
+-						{
+-							if (bb.GetBits(1)) break;
+-							newval = 0xFFFF;
+-						} else
+-						{
+-							newval = 0xFFF0 + d;
+-						}
+-					}
+-				} else
+-				{
+-					newval = d;
+-				}
+-				if (newval < 0x10000)
+-				{
+-					newval = (newval & 1) ? (UINT)(-(LONG)((newval+1) >> 1)) : (UINT)(newval >> 1);
+-					if (pblk->flags & MMCMP_DELTA)
+-					{
+-						newval += oldval;
+-						oldval = newval;
+-					} else
+-					if (!(pblk->flags & MMCMP_ABS16))
+-					{
+-						newval ^= 0x8000;
+-					}
+-					pDest[dwPos++] = (WORD)newval;
+-				}
+-				if (dwPos >= dwSize)
+-				{
+-					subblk++;
+-					dwPos = 0;
+-					dwSize = psubblk[subblk].unpk_size >> 1;
+-					pDest = (LPWORD)(pBuffer + psubblk[subblk].unpk_pos);
+-				}
+-			}
+-		} else
+-		// Data is 8-bit packed
+-		{
+-			MMCMPBITBUFFER bb;
+-			LPBYTE pDest = pBuffer + psubblk->unpk_pos;
+-			DWORD dwSize = psubblk->unpk_size;
+-			DWORD dwPos = 0;
+-			UINT numbits = pblk->num_bits;
+-			UINT subblk = 0, oldval = 0;
+-			LPCBYTE ptable = lpMemFile+dwMemPos;
+-
+-			bb.bitcount = 0;
+-			bb.bitbuffer = 0;
+-			bb.pSrc = lpMemFile+dwMemPos+pblk->tt_entries;
+-			bb.pEnd = lpMemFile+dwMemPos+pblk->pk_size;
+-			while (subblk < pblk->sub_blk)
+-			{
+-				UINT newval = 0x100;
+-				DWORD d = bb.GetBits(numbits+1);
+-
+-				if (d >= MMCMP8BitCommands[numbits])
+-				{
+-					UINT nFetch = MMCMP8BitFetch[numbits];
+-					UINT newbits = bb.GetBits(nFetch) + ((d - MMCMP8BitCommands[numbits]) << nFetch);
+-					if (newbits != numbits)
+-					{
+-						numbits = newbits & 0x07;
+-					} else
+-					{
+-						if ((d = bb.GetBits(3)) == 7)
+-						{
+-							if (bb.GetBits(1)) break;
+-							newval = 0xFF;
+-						} else
+-						{
+-							newval = 0xF8 + d;
+-						}
+-					}
+-				} else
+-				{
+-					newval = d;
+-				}
+-				if (newval < 0x100)
+-				{
+-					int n = ptable[newval];
+-					if (pblk->flags & MMCMP_DELTA)
+-					{
+-						n += oldval;
+-						oldval = n;
+-					}
+-					pDest[dwPos++] = (BYTE)n;
+-				}
+-				if (dwPos >= dwSize)
+-				{
+-					subblk++;
+-					dwPos = 0;
+-					dwSize = psubblk[subblk].unpk_size;
+-					pDest = pBuffer + psubblk[subblk].unpk_pos;
+-				}
+-			}
+-		}
+-	}
+-	*ppMemFile = pBuffer;
+-	*pdwMemLength = dwFileSize;
+-	return TRUE;
+-}
+-
+-
+-//////////////////////////////////////////////////////////////////////////////
+-//
+-// PowerPack PP20 Unpacker
+-//
+-
+-typedef struct _PPBITBUFFER
+-{
+-	UINT bitcount;
+-	ULONG bitbuffer;
+-	LPCBYTE pStart;
+-	LPCBYTE pSrc;
+-
+-	ULONG GetBits(UINT n);
+-} PPBITBUFFER;
+-
+-
+-ULONG PPBITBUFFER::GetBits(UINT n)
+-{
+-	ULONG result = 0;
+-
+-	for (UINT i=0; i<n; i++)
+-	{
+-		if (!bitcount)
+-		{
+-			bitcount = 8;
+-			if (pSrc != pStart) pSrc--;
+-			bitbuffer = *pSrc;
+-		}
+-		result = (result<<1) | (bitbuffer&1);
+-		bitbuffer >>= 1;
+-		bitcount--;
+-    }
+-    return result;
+-}
+-
+-
+-VOID PP20_DoUnpack(const BYTE *pSrc, UINT nSrcLen, BYTE *pDst, UINT nDstLen)
+-{
+-	PPBITBUFFER BitBuffer;
+-	ULONG nBytesLeft;
+-
+-	BitBuffer.pStart = pSrc;
+-	BitBuffer.pSrc = pSrc + nSrcLen - 4;
+-	BitBuffer.bitbuffer = 0;
+-	BitBuffer.bitcount = 0;
+-	BitBuffer.GetBits(pSrc[nSrcLen-1]);
+-	nBytesLeft = nDstLen;
+-	while (nBytesLeft > 0)
+-	{
+-		if (!BitBuffer.GetBits(1))
+-		{
+-			UINT n = 1;
+-			while (n < nBytesLeft)
+-			{
+-				UINT code = BitBuffer.GetBits(2);
+-				n += code;
+-				if (code != 3) break;
+-			}
+-			for (UINT i=0; i<n; i++)
+-			{
+-				pDst[--nBytesLeft] = (BYTE)BitBuffer.GetBits(8);
+-			}
+-			if (!nBytesLeft) break;
+-		}
+-		{
+-			UINT n = BitBuffer.GetBits(2)+1;
+-			UINT nbits = pSrc[n-1];
+-			UINT nofs;
+-			if (n==4)
+-			{
+-				nofs = BitBuffer.GetBits( (BitBuffer.GetBits(1)) ? nbits : 7 );
+-				while (n < nBytesLeft)
+-				{
+-					UINT code = BitBuffer.GetBits(3);
+-					n += code;
+-					if (code != 7) break;
+-				}
+-			} else
+-			{
+-				nofs = BitBuffer.GetBits(nbits);
+-			}
+-			for (UINT i=0; i<=n; i++)
+-			{
+-				pDst[nBytesLeft-1] = (nBytesLeft+nofs < nDstLen) ? pDst[nBytesLeft+nofs] : 0;
+-				if (!--nBytesLeft) break;
+-			}
+-		}
+-	}
+-}
+-
+-
+-BOOL PP20_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength)
+-{
+-	DWORD dwMemLength = *pdwMemLength;
+-	LPCBYTE lpMemFile = *ppMemFile;
+-	DWORD dwDstLen;
+-	LPBYTE pBuffer;
+-
+-	if ((!lpMemFile) || (dwMemLength < 256) || (*(DWORD *)lpMemFile != 0x30325050)) return FALSE;
+-	dwDstLen = (lpMemFile[dwMemLength-4]<<16) | (lpMemFile[dwMemLength-3]<<8) | (lpMemFile[dwMemLength-2]);
+-	//Log("PP20 detected: Packed length=%d, Unpacked length=%d\n", dwMemLength, dwDstLen);
+-	if ((dwDstLen < 512) || (dwDstLen > 0x400000) || (dwDstLen > 16*dwMemLength)) return FALSE;
+-	if ((pBuffer = (LPBYTE)GlobalAllocPtr(GHND, (dwDstLen + 31) & ~15)) == NULL) return FALSE;
+-	PP20_DoUnpack(lpMemFile+4, dwMemLength-4, pBuffer, dwDstLen);
+-	*ppMemFile = pBuffer;
+-	*pdwMemLength = dwDstLen;
+-	return TRUE;
+-}
+-
+-
+-
+-
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/snd_dsp.cxx audacious-plugins-2.5.4/src/modplug/snd_dsp.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/snd_dsp.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/snd_dsp.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,491 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-#ifdef MODPLUG_FASTSOUNDLIB
+-#define MODPLUG_NO_REVERB
+-#endif
+-
+-
+-// Delayed Surround Filters
+-#ifndef MODPLUG_FASTSOUNDLIB
+-#define nDolbyHiFltAttn		6
+-#define nDolbyHiFltMask		3
+-#define DOLBYATTNROUNDUP	31
+-#else
+-#define nDolbyHiFltAttn		3
+-#define nDolbyHiFltMask		3
+-#define DOLBYATTNROUNDUP	3
+-#endif
+-
+-// Bass Expansion
+-#define XBASS_DELAY			14	// 2.5 ms
+-
+-// Buffer Sizes
+-#define XBASSBUFFERSIZE		64		// 2 ms at 50KHz
+-#define FILTERBUFFERSIZE	64		// 1.25 ms
+-#define SURROUNDBUFFERSIZE	((MAX_SAMPLE_RATE * 50) / 1000)
+-#define REVERBBUFFERSIZE	((MAX_SAMPLE_RATE * 200) / 1000)
+-#define REVERBBUFFERSIZE2	((REVERBBUFFERSIZE*13) / 17)
+-#define REVERBBUFFERSIZE3	((REVERBBUFFERSIZE*7) / 13)
+-#define REVERBBUFFERSIZE4	((REVERBBUFFERSIZE*7) / 19)
+-
+-
+-// DSP Effects: PUBLIC members
+-UINT CSoundFile::m_nXBassDepth = 6;
+-UINT CSoundFile::m_nXBassRange = XBASS_DELAY;
+-UINT CSoundFile::m_nReverbDepth = 1;
+-UINT CSoundFile::m_nReverbDelay = 100;
+-UINT CSoundFile::m_nProLogicDepth = 12;
+-UINT CSoundFile::m_nProLogicDelay = 20;
+-
+-void (*CSoundFile::_midi_out_note)(int chan, const MODCOMMAND *m) = NULL;
+-void (*CSoundFile::_midi_out_raw)(unsigned char *,unsigned int, unsigned int) = NULL;
+-
+-////////////////////////////////////////////////////////////////////
+-// DSP Effects internal state
+-
+-// Bass Expansion: low-pass filter
+-static LONG nXBassSum = 0;
+-static LONG nXBassBufferPos = 0;
+-static LONG nXBassDlyPos = 0;
+-static LONG nXBassMask = 0;
+-
+-// Noise Reduction: simple low-pass filter
+-static LONG nLeftNR = 0;
+-static LONG nRightNR = 0;
+-
+-// Surround Encoding: 1 delay line + low-pass filter + high-pass filter
+-static LONG nSurroundSize = 0;
+-static LONG nSurroundPos = 0;
+-static LONG nDolbyDepth = 0;
+-static LONG nDolbyLoDlyPos = 0;
+-static LONG nDolbyLoFltPos = 0;
+-static LONG nDolbyLoFltSum = 0;
+-static LONG nDolbyHiFltPos = 0;
+-static LONG nDolbyHiFltSum = 0;
+-
+-// Reverb: 4 delay lines + high-pass filter + low-pass filter
+-#ifndef MODPLUG_NO_REVERB
+-static LONG nReverbSize = 0;
+-static LONG nReverbBufferPos = 0;
+-static LONG nReverbSize2 = 0;
+-static LONG nReverbBufferPos2 = 0;
+-static LONG nReverbSize3 = 0;
+-static LONG nReverbBufferPos3 = 0;
+-static LONG nReverbSize4 = 0;
+-static LONG nReverbBufferPos4 = 0;
+-static LONG nReverbLoFltSum = 0;
+-static LONG nReverbLoFltPos = 0;
+-static LONG nReverbLoDlyPos = 0;
+-static LONG nFilterAttn = 0;
+-static LONG gRvbLowPass[8];
+-static LONG gRvbLPPos = 0;
+-static LONG gRvbLPSum = 0;
+-static LONG ReverbLoFilterBuffer[XBASSBUFFERSIZE];
+-static LONG ReverbLoFilterDelay[XBASSBUFFERSIZE];
+-static LONG ReverbBuffer[REVERBBUFFERSIZE];
+-static LONG ReverbBuffer2[REVERBBUFFERSIZE2];
+-static LONG ReverbBuffer3[REVERBBUFFERSIZE3];
+-static LONG ReverbBuffer4[REVERBBUFFERSIZE4];
+-#endif
+-static LONG XBassBuffer[XBASSBUFFERSIZE];
+-static LONG XBassDelay[XBASSBUFFERSIZE];
+-static LONG DolbyLoFilterBuffer[XBASSBUFFERSIZE];
+-static LONG DolbyLoFilterDelay[XBASSBUFFERSIZE];
+-static LONG DolbyHiFilterBuffer[FILTERBUFFERSIZE];
+-static LONG SurroundBuffer[SURROUNDBUFFERSIZE];
+-
+-// Access the main temporary mix buffer directly: avoids an extra pointer
+-extern int MixSoundBuffer[MIXBUFFERSIZE*2];
+-//cextern int MixReverbBuffer[MIXBUFFERSIZE*2];
+-extern int MixReverbBuffer[MIXBUFFERSIZE*2];
+-
+-static UINT GetMaskFromSize(UINT len)
+-//-----------------------------------
+-{
+-	UINT n = 2;
+-	while (n <= len) n <<= 1;
+-	return ((n >> 1) - 1);
+-}
+-
+-
+-void CSoundFile::InitializeDSP(BOOL bReset)
+-//-----------------------------------------
+-{
+-	if (!m_nReverbDelay) m_nReverbDelay = 100;
+-	if (!m_nXBassRange) m_nXBassRange = XBASS_DELAY;
+-	if (!m_nProLogicDelay) m_nProLogicDelay = 20;
+-	if (m_nXBassDepth > 8) m_nXBassDepth = 8;
+-	if (m_nXBassDepth < 2) m_nXBassDepth = 2;
+-	if (bReset)
+-	{
+-		// Noise Reduction
+-		nLeftNR = nRightNR = 0;
+-	}
+-	// Pro-Logic Surround
+-	nSurroundPos = nSurroundSize = 0;
+-	nDolbyLoFltPos = nDolbyLoFltSum = nDolbyLoDlyPos = 0;
+-	nDolbyHiFltPos = nDolbyHiFltSum = 0;
+-	if (gdwSoundSetup & SNDMIX_SURROUND)
+-	{
+-		memset(DolbyLoFilterBuffer, 0, sizeof(DolbyLoFilterBuffer));
+-		memset(DolbyHiFilterBuffer, 0, sizeof(DolbyHiFilterBuffer));
+-		memset(DolbyLoFilterDelay, 0, sizeof(DolbyLoFilterDelay));
+-		memset(SurroundBuffer, 0, sizeof(SurroundBuffer));
+-		nSurroundSize = (gdwMixingFreq * m_nProLogicDelay) / 1000;
+-		if (nSurroundSize > SURROUNDBUFFERSIZE) nSurroundSize = SURROUNDBUFFERSIZE;
+-		if (m_nProLogicDepth < 8) nDolbyDepth = (32 >> m_nProLogicDepth) + 32;
+-		else nDolbyDepth = (m_nProLogicDepth < 16) ? (8 + (m_nProLogicDepth - 8) * 7) : 64;
+-		nDolbyDepth >>= 2;
+-	}
+-	// Reverb Setup
+-#ifndef MODPLUG_NO_REVERB
+-	if (gdwSoundSetup & SNDMIX_REVERB)
+-	{
+-		UINT nrs = (gdwMixingFreq * m_nReverbDelay) / 1000;
+-		UINT nfa = m_nReverbDepth+1;
+-		if (nrs > REVERBBUFFERSIZE) nrs = REVERBBUFFERSIZE;
+-		if ((bReset) || (nrs != (UINT)nReverbSize) || (nfa != (UINT)nFilterAttn))
+-		{
+-			nFilterAttn = nfa;
+-			nReverbSize = nrs;
+-			nReverbBufferPos = nReverbBufferPos2 = nReverbBufferPos3 = nReverbBufferPos4 = 0;
+-			nReverbLoFltSum = nReverbLoFltPos = nReverbLoDlyPos = 0;
+-			gRvbLPSum = gRvbLPPos = 0;
+-			nReverbSize2 = (nReverbSize * 13) / 17;
+-			if (nReverbSize2 > REVERBBUFFERSIZE2) nReverbSize2 = REVERBBUFFERSIZE2;
+-			nReverbSize3 = (nReverbSize * 7) / 13;
+-			if (nReverbSize3 > REVERBBUFFERSIZE3) nReverbSize3 = REVERBBUFFERSIZE3;
+-			nReverbSize4 = (nReverbSize * 7) / 19;
+-			if (nReverbSize4 > REVERBBUFFERSIZE4) nReverbSize4 = REVERBBUFFERSIZE4;
+-			memset(ReverbLoFilterBuffer, 0, sizeof(ReverbLoFilterBuffer));
+-			memset(ReverbLoFilterDelay, 0, sizeof(ReverbLoFilterDelay));
+-			memset(ReverbBuffer, 0, sizeof(ReverbBuffer));
+-			memset(ReverbBuffer2, 0, sizeof(ReverbBuffer2));
+-			memset(ReverbBuffer3, 0, sizeof(ReverbBuffer3));
+-			memset(ReverbBuffer4, 0, sizeof(ReverbBuffer4));
+-			memset(gRvbLowPass, 0, sizeof(gRvbLowPass));
+-/* mrsb: libmodplug bug hahahah */
+-			memset(MixSoundBuffer,0,sizeof(MixSoundBuffer));
+-			memset(MixReverbBuffer,0,sizeof(MixReverbBuffer));
+-		}
+-	} else nReverbSize = 0;
+-#endif
+-	BOOL bResetBass = FALSE;
+-	// Bass Expansion Reset
+-	if (gdwSoundSetup & SNDMIX_MEGABASS)
+-	{
+-		UINT nXBassSamples = (gdwMixingFreq * m_nXBassRange) / 10000;
+-		if (nXBassSamples > XBASSBUFFERSIZE) nXBassSamples = XBASSBUFFERSIZE;
+-		UINT mask = GetMaskFromSize(nXBassSamples);
+-		if ((bReset) || (mask != (UINT)nXBassMask))
+-		{
+-			nXBassMask = mask;
+-			bResetBass = TRUE;
+-		}
+-	} else
+-	{
+-		nXBassMask = 0;
+-		bResetBass = TRUE;
+-	}
+-	if (bResetBass)
+-	{
+-		nXBassSum = nXBassBufferPos = nXBassDlyPos = 0;
+-		memset(XBassBuffer, 0, sizeof(XBassBuffer));
+-		memset(XBassDelay, 0, sizeof(XBassDelay));
+-	}
+-}
+-
+-
+-void CSoundFile::ProcessStereoDSP(int count)
+-//------------------------------------------
+-{
+-#ifndef MODPLUG_NO_REVERB
+-	// Reverb
+-	if (gdwSoundSetup & SNDMIX_REVERB)
+-	{
+-		int *pr = MixSoundBuffer, *pin = MixReverbBuffer, rvbcount = count;
+-		do
+-		{
+-			int echo = ReverbBuffer[nReverbBufferPos] + ReverbBuffer2[nReverbBufferPos2]
+-					+ ReverbBuffer3[nReverbBufferPos3] + ReverbBuffer4[nReverbBufferPos4];	// echo = reverb signal
+-			// Delay line and remove Low Frequencies			// v = original signal
+-			int echodly = ReverbLoFilterDelay[nReverbLoDlyPos];	// echodly = delayed signal
+-			ReverbLoFilterDelay[nReverbLoDlyPos] = echo >> 1;
+-			nReverbLoDlyPos++;
+-			nReverbLoDlyPos &= 0x1F;
+-			int n = nReverbLoFltPos;
+-			nReverbLoFltSum -= ReverbLoFilterBuffer[n];
+-			int tmp = echo / 128;
+-			ReverbLoFilterBuffer[n] = tmp;
+-			nReverbLoFltSum += tmp;
+-			echodly -= nReverbLoFltSum;
+-			nReverbLoFltPos = (n + 1) & 0x3F;
+-			// Reverb
+-			int v = (pin[0]+pin[1]) >> nFilterAttn;
+-			pr[0] += pin[0] + echodly;
+-			pr[1] += pin[1] + echodly;
+-			v += echodly >> 2;
+-			ReverbBuffer3[nReverbBufferPos3] = v;
+-			ReverbBuffer4[nReverbBufferPos4] = v;
+-			v += echodly >> 4;
+-			v >>= 1;
+-			gRvbLPSum -= gRvbLowPass[gRvbLPPos];
+-			gRvbLPSum += v;
+-			gRvbLowPass[gRvbLPPos] = v;
+-			gRvbLPPos++;
+-			gRvbLPPos &= 7;
+-			int vlp = gRvbLPSum >> 2;
+-			ReverbBuffer[nReverbBufferPos] = vlp;
+-			ReverbBuffer2[nReverbBufferPos2] = vlp;
+-			if (++nReverbBufferPos >= nReverbSize) nReverbBufferPos = 0;
+-			if (++nReverbBufferPos2 >= nReverbSize2) nReverbBufferPos2 = 0;
+-			if (++nReverbBufferPos3 >= nReverbSize3) nReverbBufferPos3 = 0;
+-			if (++nReverbBufferPos4 >= nReverbSize4) nReverbBufferPos4 = 0;
+-			pr += 2;
+-			pin += 2;
+-		} while (--rvbcount);
+-	}
+-#endif
+-	// Dolby Pro-Logic Surround
+-	if (gdwSoundSetup & SNDMIX_SURROUND)
+-	{
+-		int *pr = MixSoundBuffer, n = nDolbyLoFltPos;
+-		for (int r=count; r; r--)
+-		{
+-			int v = (pr[0]+pr[1]+DOLBYATTNROUNDUP) >> (nDolbyHiFltAttn+1);
+-#ifndef MODPLUG_FASTSOUNDLIB
+-			v *= (int)nDolbyDepth;
+-#endif
+-			// Low-Pass Filter
+-			nDolbyHiFltSum -= DolbyHiFilterBuffer[nDolbyHiFltPos];
+-			DolbyHiFilterBuffer[nDolbyHiFltPos] = v;
+-			nDolbyHiFltSum += v;
+-			v = nDolbyHiFltSum;
+-			nDolbyHiFltPos++;
+-			nDolbyHiFltPos &= nDolbyHiFltMask;
+-			// Surround
+-			int secho = SurroundBuffer[nSurroundPos];
+-			SurroundBuffer[nSurroundPos] = v;
+-			// Delay line and remove low frequencies
+-			v = DolbyLoFilterDelay[nDolbyLoDlyPos];		// v = delayed signal
+-			DolbyLoFilterDelay[nDolbyLoDlyPos] = secho;	// secho = signal
+-			nDolbyLoDlyPos++;
+-			nDolbyLoDlyPos &= 0x1F;
+-			nDolbyLoFltSum -= DolbyLoFilterBuffer[n];
+-			int tmp = secho / 64;
+-			DolbyLoFilterBuffer[n] = tmp;
+-			nDolbyLoFltSum += tmp;
+-			v -= nDolbyLoFltSum;
+-			n++;
+-			n &= 0x3F;
+-			// Add echo
+-			pr[0] += v;
+-			pr[1] -= v;
+-			if (++nSurroundPos >= nSurroundSize) nSurroundPos = 0;
+-			pr += 2;
+-		}
+-		nDolbyLoFltPos = n;
+-	}
+-	// Bass Expansion
+-	if (gdwSoundSetup & SNDMIX_MEGABASS)
+-	{
+-		int *px = MixSoundBuffer;
+-		int xba = m_nXBassDepth+1, xbamask = (1 << xba) - 1;
+-		int n = nXBassBufferPos;
+-		for (int x=count; x; x--)
+-		{
+-			nXBassSum -= XBassBuffer[n];
+-			int tmp0 = px[0] + px[1];
+-			int tmp = (tmp0 + ((tmp0 >> 31) & xbamask)) >> xba;
+-			XBassBuffer[n] = tmp;
+-			nXBassSum += tmp;
+-			int v = XBassDelay[nXBassDlyPos];
+-			XBassDelay[nXBassDlyPos] = px[0];
+-			px[0] = v + nXBassSum;
+-			v = XBassDelay[nXBassDlyPos+1];
+-			XBassDelay[nXBassDlyPos+1] = px[1];
+-			px[1] = v + nXBassSum;
+-			nXBassDlyPos = (nXBassDlyPos + 2) & nXBassMask;
+-			px += 2;
+-			n++;
+-			n &= nXBassMask;
+-		}
+-		nXBassBufferPos = n;
+-	}
+-	// Noise Reduction
+-	if (gdwSoundSetup & SNDMIX_NOISEREDUCTION)
+-	{
+-		int n1 = nLeftNR, n2 = nRightNR;
+-		int *pnr = MixSoundBuffer;
+-		for (int nr=count; nr; nr--)
+-		{
+-			int vnr = pnr[0] >> 1;
+-			pnr[0] = vnr + n1;
+-			n1 = vnr;
+-			vnr = pnr[1] >> 1;
+-			pnr[1] = vnr + n2;
+-			n2 = vnr;
+-			pnr += 2;
+-		}
+-		nLeftNR = n1;
+-		nRightNR = n2;
+-	}
+-}
+-
+-
+-void CSoundFile::ProcessMonoDSP(int count)
+-//----------------------------------------
+-{
+-#ifndef MODPLUG_NO_REVERB
+-	// Reverb
+-	if (gdwSoundSetup & SNDMIX_REVERB)
+-	{
+-		int *pr = MixSoundBuffer, rvbcount = count, *pin = MixReverbBuffer;
+-		do
+-		{
+-			int echo = ReverbBuffer[nReverbBufferPos] + ReverbBuffer2[nReverbBufferPos2]
+-					+ ReverbBuffer3[nReverbBufferPos3] + ReverbBuffer4[nReverbBufferPos4];	// echo = reverb signal
+-			// Delay line and remove Low Frequencies			// v = original signal
+-			int echodly = ReverbLoFilterDelay[nReverbLoDlyPos];	// echodly = delayed signal
+-			ReverbLoFilterDelay[nReverbLoDlyPos] = echo >> 1;
+-			nReverbLoDlyPos++;
+-			nReverbLoDlyPos &= 0x1F;
+-			int n = nReverbLoFltPos;
+-			nReverbLoFltSum -= ReverbLoFilterBuffer[n];
+-			int tmp = echo / 128;
+-			ReverbLoFilterBuffer[n] = tmp;
+-			nReverbLoFltSum += tmp;
+-			echodly -= nReverbLoFltSum;
+-			nReverbLoFltPos = (n + 1) & 0x3F;
+-			// Reverb
+-			int v = pin[0] >> (nFilterAttn-1);
+-			*pr++ += pin[0] + echodly;
+-			pin++;
+-			v += echodly >> 2;
+-			ReverbBuffer3[nReverbBufferPos3] = v;
+-			ReverbBuffer4[nReverbBufferPos4] = v;
+-			v += echodly >> 4;
+-			v >>= 1;
+-			gRvbLPSum -= gRvbLowPass[gRvbLPPos];
+-			gRvbLPSum += v;
+-			gRvbLowPass[gRvbLPPos] = v;
+-			gRvbLPPos++;
+-			gRvbLPPos &= 7;
+-			int vlp = gRvbLPSum >> 2;
+-			ReverbBuffer[nReverbBufferPos] = vlp;
+-			ReverbBuffer2[nReverbBufferPos2] = vlp;
+-			if (++nReverbBufferPos >= nReverbSize) nReverbBufferPos = 0;
+-			if (++nReverbBufferPos2 >= nReverbSize2) nReverbBufferPos2 = 0;
+-			if (++nReverbBufferPos3 >= nReverbSize3) nReverbBufferPos3 = 0;
+-			if (++nReverbBufferPos4 >= nReverbSize4) nReverbBufferPos4 = 0;
+-		} while (--rvbcount);
+-	}
+-#endif
+-	// Bass Expansion
+-	if (gdwSoundSetup & SNDMIX_MEGABASS)
+-	{
+-		int *px = MixSoundBuffer;
+-		int xba = m_nXBassDepth, xbamask = (1 << xba)-1;
+-		int n = nXBassBufferPos;
+-		for (int x=count; x; x--)
+-		{
+-			nXBassSum -= XBassBuffer[n];
+-			int tmp0 = *px;
+-			int tmp = (tmp0 + ((tmp0 >> 31) & xbamask)) >> xba;
+-			XBassBuffer[n] = tmp;
+-			nXBassSum += tmp;
+-			int v = XBassDelay[nXBassDlyPos];
+-			XBassDelay[nXBassDlyPos] = *px;
+-			*px++ = v + nXBassSum;
+-			nXBassDlyPos = (nXBassDlyPos + 2) & nXBassMask;
+-			n++;
+-			n &= nXBassMask;
+-		}
+-		nXBassBufferPos = n;
+-	}
+-	// Noise Reduction
+-	if (gdwSoundSetup & SNDMIX_NOISEREDUCTION)
+-	{
+-		int n = nLeftNR;
+-		int *pnr = MixSoundBuffer;
+-		for (int nr=count; nr; pnr++, nr--)
+-		{
+-			int vnr = *pnr >> 1;
+-			*pnr = vnr + n;
+-			n = vnr;
+-		}
+-		nLeftNR = n;
+-	}
+-}
+-
+-
+-/////////////////////////////////////////////////////////////////
+-// Clean DSP Effects interface
+-
+-// [Reverb level 0(quiet)-100(loud)], [delay in ms, usually 40-200ms]
+-BOOL CSoundFile::SetReverbParameters(UINT nDepth, UINT nDelay)
+-//------------------------------------------------------------
+-{
+-	if (nDepth > 100) nDepth = 100;
+-	UINT gain = nDepth / 20;
+-	if (gain > 4) gain = 4;
+-	m_nReverbDepth = 4 - gain;
+-	if (nDelay < 40) nDelay = 40;
+-	if (nDelay > 250) nDelay = 250;
+-	m_nReverbDelay = nDelay;
+-	return TRUE;
+-}
+-
+-
+-// [XBass level 0(quiet)-100(loud)], [cutoff in Hz 20-100]
+-BOOL CSoundFile::SetXBassParameters(UINT nDepth, UINT nRange)
+-//-----------------------------------------------------------
+-{
+-	if (nDepth > 100) nDepth = 100;
+-	UINT gain = nDepth / 20;
+-	if (gain > 4) gain = 4;
+-	m_nXBassDepth = 8 - gain;	// filter attenuation 1/256 .. 1/16
+-	UINT range = nRange / 5;
+-	if (range > 5) range -= 5; else range = 0;
+-	if (nRange > 16) nRange = 16;
+-	m_nXBassRange = 21 - range;	// filter average on 0.5-1.6ms
+-	return TRUE;
+-}
+-
+-
+-// [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-50ms]
+-BOOL CSoundFile::SetSurroundParameters(UINT nDepth, UINT nDelay)
+-//--------------------------------------------------------------
+-{
+-	UINT gain = (nDepth * 16) / 100;
+-	if (gain > 16) gain = 16;
+-	if (gain < 1) gain = 1;
+-	m_nProLogicDepth = gain;
+-	if (nDelay < 4) nDelay = 4;
+-	if (nDelay > 50) nDelay = 50;
+-	m_nProLogicDelay = nDelay;
+-	return TRUE;
+-}
+-
+-BOOL CSoundFile::SetWaveConfigEx(BOOL bSurround,BOOL /*bNoOverSampling*/,BOOL bReverb,BOOL hqido,BOOL bMegaBass,BOOL bNR,BOOL bEQ)
+-//----------------------------------------------------------------------------------------------------------------------------
+-{
+-	DWORD d = gdwSoundSetup & ~(SNDMIX_SURROUND | SNDMIX_NORESAMPLING | SNDMIX_REVERB | SNDMIX_HQRESAMPLER | SNDMIX_MEGABASS | SNDMIX_NOISEREDUCTION | SNDMIX_EQ);
+-	if (bSurround) d |= SNDMIX_SURROUND;
+-//	if (bNoOverSampling) d |= SNDMIX_NORESAMPLING;
+-	if (bReverb) d |= SNDMIX_REVERB;
+-	if (hqido) d |= SNDMIX_HQRESAMPLER;
+-	if (bMegaBass) d |= SNDMIX_MEGABASS;
+-	if (bNR) d |= SNDMIX_NOISEREDUCTION;
+-	if (bEQ) d |= SNDMIX_EQ;
+-	gdwSoundSetup = d;
+-	InitPlayer(FALSE);
+-	return TRUE;
+-}
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/snd_eq.cxx audacious-plugins-2.5.4/src/modplug/snd_eq.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/snd_eq.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/snd_eq.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,228 +0,0 @@
+-/*
+- * This program is  free software; you can redistribute it  and modify it
+- * under the terms of the GNU  General Public License as published by the
+- * Free Software Foundation; either version 2  of the license or (at your
+- * option) any later version.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+- *
+- * Name                Date             Description
+- * 
+- * Olivier Lapicque    --/--/--         Creation
+- * Trevor Nunes        26/01/04         conditional compilation for AMD,MMX calls
+- *
+-*/
+-#include "stdafx.h"
+-#include "sndfile.h"
+-#include <math.h>
+-
+-
+-#define EQ_BANDWIDTH	2.0
+-#define EQ_ZERO			0.000001
+-#define REAL			float
+-
+-extern REAL MixFloatBuffer[];
+-
+-extern void StereoMixToFloat(const int *pSrc, float *pOut1, float *pOut2, UINT nCount);
+-extern void FloatToStereoMix(const float *pIn1, const float *pIn2, int *pOut, UINT nCount);
+-extern void MonoMixToFloat(const int *pSrc, float *pOut, UINT nCount);
+-extern void FloatToMonoMix(const float *pIn, int *pOut, UINT nCount);
+-
+-typedef struct _EQBANDSTRUCT
+-{
+-	REAL a0, a1, a2, b1, b2;
+-	REAL x1, x2, y1, y2;
+-	REAL Gain, CenterFrequency;
+-	BOOL bEnable;
+-} EQBANDSTRUCT, *PEQBANDSTRUCT;
+-
+-UINT gEqLinearToDB[33] =
+-{
+-	16, 19, 22, 25, 28, 31, 34, 37,
+-	40, 43, 46, 49, 52, 55, 58, 61,
+-	64, 76, 88, 100, 112, 124, 136, 148,
+-	160, 172, 184, 196, 208, 220, 232, 244, 256
+-};
+-
+-
+-//static REAL f2ic = (REAL)(1 << 28);
+-//static REAL i2fc = (REAL)(1.0 / (1 << 28));
+-
+-static EQBANDSTRUCT gEQ[MAX_EQ_BANDS*2] =
+-{
+-	// Default: Flat EQ
+-	{0,0,0,0,0, 0,0,0,0, 1,   120, FALSE},
+-	{0,0,0,0,0, 0,0,0,0, 1,   600, FALSE},
+-	{0,0,0,0,0, 0,0,0,0, 1,  1200, FALSE},
+-	{0,0,0,0,0, 0,0,0,0, 1,  3000, FALSE},
+-	{0,0,0,0,0, 0,0,0,0, 1,  6000, FALSE},
+-	{0,0,0,0,0, 0,0,0,0, 1, 10000, FALSE},
+-	{0,0,0,0,0, 0,0,0,0, 1,   120, FALSE},
+-	{0,0,0,0,0, 0,0,0,0, 1,   600, FALSE},
+-	{0,0,0,0,0, 0,0,0,0, 1,  1200, FALSE},
+-	{0,0,0,0,0, 0,0,0,0, 1,  3000, FALSE},
+-	{0,0,0,0,0, 0,0,0,0, 1,  6000, FALSE},
+-	{0,0,0,0,0, 0,0,0,0, 1, 10000, FALSE},
+-};
+-
+-void EQFilter(EQBANDSTRUCT *pbs, REAL *pbuffer, UINT nCount)
+-//----------------------------------------------------------
+-{
+-	for (UINT i=0; i<nCount; i++)
+-	{
+-		REAL x = pbuffer[i];
+-		REAL y = pbs->a1 * pbs->x1 + pbs->a2 * pbs->x2 + pbs->a0 * x + pbs->b1 * pbs->y1 + pbs->b2 * pbs->y2;
+-		pbs->x2 = pbs->x1;
+-		pbs->y2 = pbs->y1;
+-		pbs->x1 = x;
+-		pbuffer[i] = y;
+-		pbs->y1 = y;
+-	}
+-}
+-
+-void CSoundFile::EQMono(int *pbuffer, UINT nCount)
+-//------------------------------------------------
+-{
+-	MonoMixToFloat(pbuffer, MixFloatBuffer, nCount);
+-	for (UINT b=0; b<MAX_EQ_BANDS; b++)
+-	{
+-		if ((gEQ[b].bEnable) && (gEQ[b].Gain != 1.0f))
+-			EQFilter(&gEQ[b], MixFloatBuffer, nCount);
+-	}
+-	FloatToMonoMix(MixFloatBuffer, pbuffer, nCount);
+-}
+-
+-void CSoundFile::EQStereo(int *pbuffer, UINT nCount)
+-//--------------------------------------------------
+-{
+-	StereoMixToFloat(pbuffer, MixFloatBuffer, MixFloatBuffer+MIXBUFFERSIZE, nCount);
+-		
+-	for (UINT bl=0; bl<MAX_EQ_BANDS; bl++)
+-	{
+-		if ((gEQ[bl].bEnable) && (gEQ[bl].Gain != 1.0f))
+-			EQFilter(&gEQ[bl], MixFloatBuffer, nCount);
+-	}
+-	for (UINT br=MAX_EQ_BANDS; br<MAX_EQ_BANDS*2; br++)
+-	{
+-		if ((gEQ[br].bEnable) && (gEQ[br].Gain != 1.0f))
+-			EQFilter(&gEQ[br], MixFloatBuffer+MIXBUFFERSIZE, nCount);
+-	}
+-
+-	FloatToStereoMix(MixFloatBuffer, MixFloatBuffer+MIXBUFFERSIZE, pbuffer, nCount);
+-
+-}
+-
+-void CSoundFile::InitializeEQ(BOOL bReset)
+-//----------------------------------------
+-{
+-	REAL fMixingFreq = (REAL)gdwMixingFreq;
+-	// Gain = 0.5 (-6dB) .. 2 (+6dB)
+-	for (UINT band=0; band<MAX_EQ_BANDS*2; band++) if (gEQ[band].bEnable)
+-	{
+-		REAL k, k2, r, f;
+-		REAL v0, v1;
+-		BOOL b = bReset;
+-
+-		f = gEQ[band].CenterFrequency / fMixingFreq;
+-		if (f > 0.45f) gEQ[band].Gain = 1;
+-		// if (f > 0.25) f = 0.25;
+-		// k = tan(PI*f);
+-		k = f * 3.141592654f;
+-		k = k + k*f;
+-//		if (k > (REAL)0.707) k = (REAL)0.707;
+-		k2 = k*k;
+-		v0 = gEQ[band].Gain;
+-		v1 = 1;
+-		if (gEQ[band].Gain < 1.0)
+-		{
+-			v0 *= (0.5f/EQ_BANDWIDTH);
+-			v1 *= (0.5f/EQ_BANDWIDTH);
+-		} else
+-		{
+-			v0 *= (1.0f/EQ_BANDWIDTH);
+-			v1 *= (1.0f/EQ_BANDWIDTH);
+-		}
+-		r = (1 + v0*k + k2) / (1 + v1*k + k2);
+-		if (r != gEQ[band].a0)
+-		{
+-			gEQ[band].a0 = r;
+-			b = TRUE;
+-		}
+-		r = 2 * (k2 - 1) / (1 + v1*k + k2);
+-		if (r != gEQ[band].a1)
+-		{
+-			gEQ[band].a1 = r;
+-			b = TRUE;
+-		}
+-		r = (1 - v0*k + k2) / (1 + v1*k + k2);
+-		if (r != gEQ[band].a2)
+-		{
+-			gEQ[band].a2 = r;
+-			b = TRUE;
+-		}
+-		r = - 2 * (k2 - 1) / (1 + v1*k + k2);
+-		if (r != gEQ[band].b1)
+-		{
+-			gEQ[band].b1 = r;
+-			b = TRUE;
+-		}
+-		r = - (1 - v1*k + k2) / (1 + v1*k + k2);
+-		if (r != gEQ[band].b2)
+-		{
+-			gEQ[band].b2 = r;
+-			b = TRUE;
+-		}
+-		if (b)
+-		{
+-			gEQ[band].x1 = 0;
+-			gEQ[band].x2 = 0;
+-			gEQ[band].y1 = 0;
+-			gEQ[band].y2 = 0;
+-		}
+-	} else
+-	{
+-		gEQ[band].a0 = 0;
+-		gEQ[band].a1 = 0;
+-		gEQ[band].a2 = 0;
+-		gEQ[band].b1 = 0;
+-		gEQ[band].b2 = 0;
+-		gEQ[band].x1 = 0;
+-		gEQ[band].x2 = 0;
+-		gEQ[band].y1 = 0;
+-		gEQ[band].y2 = 0;
+-	}
+-}
+-
+-
+-void CSoundFile::SetEQGains(const UINT *pGains, UINT nGains, const UINT *pFreqs, BOOL bReset)
+-//-------------------------------------------------------------------------------------------
+-{
+-	for (UINT i=0; i<MAX_EQ_BANDS; i++)
+-	{
+-		REAL g, f = 0;
+-		if (i < nGains)
+-		{
+-			UINT n = pGains[i];
+-//			if (n > 32) n = 32;
+-			g = 1.0 + (((double)n) / 64.0);
+-			if (pFreqs) f = (REAL)(int)pFreqs[i];
+-		} else
+-		{
+-			g = 1;
+-		}
+-		gEQ[i].Gain = g;
+-		gEQ[i].CenterFrequency = f;
+-		gEQ[i+MAX_EQ_BANDS].Gain = g;
+-		gEQ[i+MAX_EQ_BANDS].CenterFrequency = f;
+-		if (f > 20.0f && i < nGains) /* don't enable bands outside... */
+-		{
+-			gEQ[i].bEnable = TRUE;
+-			gEQ[i+MAX_EQ_BANDS].bEnable = TRUE;
+-		} else
+-		{
+-			gEQ[i].bEnable = FALSE;
+-			gEQ[i+MAX_EQ_BANDS].bEnable = FALSE;
+-		}
+-	}
+-	InitializeEQ(bReset);
+-}
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/sndfile.cxx audacious-plugins-2.5.4/src/modplug/sndfile.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/sndfile.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/sndfile.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,1690 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>,
+- *          Adam Goode       <adam at evdebs.org> (endian and char fixes for PPC)
+-*/
+-
+-#include <math.h>       //for GCCFIX
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-#define MMCMP_SUPPORT
+-
+-#ifdef MMCMP_SUPPORT
+-extern BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength);
+-#endif
+-
+-
+-// External decompressors
+-extern void AMSUnpack(const char *psrc, UINT inputlen, char *pdest, UINT dmax, char packcharacter);
+-extern WORD MDLReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n);
+-extern int DMFUnpack(LPBYTE psample, LPBYTE ibuf, LPBYTE ibufmax, UINT maxlen);
+-extern DWORD ITReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n);
+-extern void ITUnpack8Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215);
+-extern void ITUnpack16Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215);
+-
+-
+-#define MAX_PACK_TABLES		3
+-
+-
+-// Compression table
+-static signed char UnpackTable[MAX_PACK_TABLES][16] =
+-//--------------------------------------------
+-{
+-	// CPU-generated dynamic table
+-	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+-	// u-Law table
+-	{0, 1, 2, 4, 8, 16, 32, 64,
+-	-1, -2, -4, -8, -16, -32, -48, -64},
+-	// Linear table
+-	{0, 1, 2, 3, 5, 7, 12, 19,
+-	-1, -2, -3, -5, -7, -12, -19, -31}
+-};
+-
+-
+-//////////////////////////////////////////////////////////
+-// CSoundFile
+-
+-CSoundFile::CSoundFile()
+-//----------------------
+-{
+-	m_nType = MOD_TYPE_NONE;
+-	m_dwSongFlags = 0;
+-	m_nStereoSeparation = 128;
+-	m_nChannels = 0;
+-	m_nMixChannels = 0;
+-	m_nSamples = 0;
+-	m_nInstruments = 0;
+-	m_nPatternNames = 0;
+-	m_lpszPatternNames = NULL;
+-	m_lpszSongComments = NULL;
+-	m_nFreqFactor = m_nTempoFactor = 128;
+-	m_nMasterVolume = 128;
+-	m_nMinPeriod = 0x20;
+-	m_nMaxPeriod = 0x7FFF;
+-	m_nRepeatCount = 0;
+-	m_rowHighlightMajor = 16;
+-	m_rowHighlightMinor = 4;
+-	memset(Chn, 0, sizeof(Chn));
+-	memset(ChnMix, 0, sizeof(ChnMix));
+-	memset(Ins, 0, sizeof(Ins));
+-	memset(ChnSettings, 0, sizeof(ChnSettings));
+-	memset(Headers, 0, sizeof(Headers));
+-	memset(Order, 0xFF, sizeof(Order));
+-	memset(Patterns, 0, sizeof(Patterns));
+-	memset(m_szNames, 0, sizeof(m_szNames));
+-	memset(m_MixPlugins, 0, sizeof(m_MixPlugins));
+-}
+-
+-
+-CSoundFile::~CSoundFile()
+-//-----------------------
+-{
+-	Destroy();
+-}
+-
+-
+-BOOL CSoundFile::Create(LPCBYTE lpStream, DWORD dwMemLength)
+-//----------------------------------------------------------
+-{
+-	int i;
+-
+-	// deja vu...
+-	m_nType = MOD_TYPE_NONE;
+-	m_dwSongFlags = 0;
+-	m_nStereoSeparation = 128;
+-	m_nChannels = 0;
+-	m_nMixChannels = 0;
+-	m_nSamples = 0;
+-	m_nInstruments = 0;
+-	m_nFreqFactor = m_nTempoFactor = 128;
+-	m_nMasterVolume = 128;
+-	m_nDefaultGlobalVolume = 256;
+-	m_nGlobalVolume = 256;
+-	m_nOldGlbVolSlide = 0;
+-	m_nDefaultSpeed = 6;
+-	m_nDefaultTempo = 125;
+-	m_nPatternDelay = 0;
+-	m_nFrameDelay = 0;
+-	m_nNextRow = 0;
+-	m_nRow = 0;
+-	m_nPattern = 0;
+-	m_nCurrentPattern = 0;
+-	m_nNextPattern = 0;
+-	m_nRestartPos = 0;
+-	m_nMinPeriod = 16;
+-	m_nMaxPeriod = 32767;
+-	m_nSongPreAmp = 0x30;
+-	m_nPatternNames = 0;
+-	m_lpszPatternNames = NULL;
+-	m_lpszSongComments = NULL;
+-	memset(Ins, 0, sizeof(Ins));
+-	memset(ChnMix, 0, sizeof(ChnMix));
+-	memset(Chn, 0, sizeof(Chn));
+-	memset(Headers, 0, sizeof(Headers));
+-	memset(Order, 0xFF, sizeof(Order));
+-	memset(Patterns, 0, sizeof(Patterns));
+-	memset(m_szNames, 0, sizeof(m_szNames));
+-	memset(m_MixPlugins, 0, sizeof(m_MixPlugins));
+-	ResetMidiCfg();
+-	for (UINT npt=0; npt<MAX_PATTERNS; npt++) {
+-		PatternSize[npt] = 64;
+-		PatternAllocSize[npt] = 64;
+-	}
+-	for (UINT nch=0; nch<MAX_BASECHANNELS; nch++)
+-	{
+-		ChnSettings[nch].nPan = 128;
+-		ChnSettings[nch].nVolume = 64;
+-		ChnSettings[nch].dwFlags = 0;
+-		ChnSettings[nch].szName[0] = 0;
+-	}
+-	if (lpStream)
+-	{
+-#ifdef MMCMP_SUPPORT
+-		BOOL bMMCmp = MMCMP_Unpack(&lpStream, &dwMemLength);
+-#endif
+-		if ((!ReadXM(lpStream, dwMemLength))
+-		 && (!Read669(lpStream, dwMemLength))
+-		 && (!ReadS3M(lpStream, dwMemLength))
+-		 && (!ReadIT(lpStream, dwMemLength))
+-		 && (!ReadWav(lpStream, dwMemLength))
+-		 && (!ReadSTM(lpStream, dwMemLength))
+-		 && (!ReadMed(lpStream, dwMemLength))
+-		 && (!ReadMTM(lpStream, dwMemLength))
+-		 && (!ReadMDL(lpStream, dwMemLength))
+-		 && (!ReadDBM(lpStream, dwMemLength))
+-		 && (!ReadFAR(lpStream, dwMemLength))
+-		 && (!ReadAMS(lpStream, dwMemLength))
+-		 && (!ReadOKT(lpStream, dwMemLength))
+-		 && (!ReadPTM(lpStream, dwMemLength))
+-		 && (!ReadUlt(lpStream, dwMemLength))
+-		 && (!ReadDMF(lpStream, dwMemLength))
+-		 && (!ReadDSM(lpStream, dwMemLength))
+-		 && (!ReadUMX(lpStream, dwMemLength))
+-		 && (!ReadAMF(lpStream, dwMemLength))
+-		 && (!ReadPSM(lpStream, dwMemLength))
+-		 && (!ReadMT2(lpStream, dwMemLength))
+-		 && (!ReadMod(lpStream, dwMemLength))) m_nType = MOD_TYPE_NONE;
+-#ifdef MMCMP_SUPPORT
+-		if (bMMCmp)
+-		{
+-			GlobalFreePtr(lpStream);
+-			lpStream = NULL;
+-		}
+-#endif
+-	}
+-	// Adjust channels
+-	for (i=0; i<MAX_BASECHANNELS; i++)
+-	{
+-		if (ChnSettings[i].nVolume > 64) ChnSettings[i].nVolume = 64;
+-		if (ChnSettings[i].nPan > 256) ChnSettings[i].nPan = 128;
+-		Chn[i].nPan = ChnSettings[i].nPan;
+-		Chn[i].nGlobalVol = ChnSettings[i].nVolume;
+-		Chn[i].dwFlags = ChnSettings[i].dwFlags;
+-		Chn[i].nVolume = 256;
+-		Chn[i].nCutOff = 0x7F;
+-	}
+-	// Checking instruments
+-	MODINSTRUMENT *pins = Ins;
+-
+-	for (i=0; i<MAX_INSTRUMENTS; i++, pins++)
+-	{
+-		if (pins->pSample)
+-		{
+-			if (pins->nLoopEnd > pins->nLength) pins->nLoopEnd = pins->nLength;
+-			if (pins->nSustainEnd > pins->nLength) pins->nSustainEnd = pins->nLength;
+-		} else {
+-			pins->nLength = 0;
+-			pins->nLoopStart = 0;
+-			pins->nLoopEnd = 0;
+-			pins->nSustainStart = 0;
+-			pins->nSustainEnd = 0;
+-		}
+-		if (!pins->nLoopEnd) pins->uFlags &= ~CHN_LOOP;
+-		if (!pins->nSustainEnd) pins->uFlags &= ~CHN_SUSTAINLOOP;
+-		if (pins->nGlobalVol > 64) pins->nGlobalVol = 64;
+-	}
+-	// Check invalid instruments
+-	while ((m_nInstruments > 0) && (!Headers[m_nInstruments])) m_nInstruments--;
+-	// Set default values
+-	if (m_nDefaultTempo < 31) m_nDefaultTempo = 31;
+-	if (!m_nDefaultSpeed) m_nDefaultSpeed = 6;
+-	m_nMusicSpeed = m_nDefaultSpeed;
+-	m_nMusicTempo = m_nDefaultTempo;
+-	m_nGlobalVolume = m_nDefaultGlobalVolume;
+-	m_nNextPattern = 0;
+-	m_nCurrentPattern = 0;
+-	m_nPattern = 0;
+-	m_nBufferCount = 0;
+-	m_nTickCount = m_nMusicSpeed;
+-	m_nNextRow = 0;
+-	m_nRow = 0;
+-	if ((m_nRestartPos >= MAX_ORDERS) || (Order[m_nRestartPos] >= MAX_PATTERNS)) m_nRestartPos = 0;
+-	// Load plugins
+-	if (gpMixPluginCreateProc)
+-	{
+-		for (UINT iPlug=0; iPlug<MAX_MIXPLUGINS; iPlug++)
+-		{
+-			if ((m_MixPlugins[iPlug].Info.dwPluginId1)
+-			 || (m_MixPlugins[iPlug].Info.dwPluginId2))
+-			{
+-				gpMixPluginCreateProc(&m_MixPlugins[iPlug]);
+-				if (m_MixPlugins[iPlug].pMixPlugin)
+-				{
+-					m_MixPlugins[iPlug].pMixPlugin->RestoreAllParameters();
+-				}
+-			}
+-		}
+-	}
+-	return m_nType ? TRUE : FALSE;
+-}
+-
+-
+-BOOL CSoundFile::Destroy()
+-
+-//------------------------
+-{
+-	int i;
+-	for (i=0; i<MAX_PATTERNS; i++) if (Patterns[i])
+-	{
+-		FreePattern(Patterns[i]);
+-		Patterns[i] = NULL;
+-	}
+-	m_nPatternNames = 0;
+-	if (m_lpszPatternNames)
+-	{
+-		delete m_lpszPatternNames;
+-		m_lpszPatternNames = NULL;
+-	}
+-	if (m_lpszSongComments)
+-	{
+-		delete m_lpszSongComments;
+-		m_lpszSongComments = NULL;
+-	}
+-	for (i=1; i<MAX_SAMPLES; i++)
+-	{
+-		MODINSTRUMENT *pins = &Ins[i];
+-		if (pins->pSample)
+-		{
+-			FreeSample(pins->pSample);
+-			pins->pSample = NULL;
+-		}
+-	}
+-	for (i=0; i<MAX_INSTRUMENTS; i++)
+-	{
+-		if (Headers[i])
+-		{
+-			delete Headers[i];
+-			Headers[i] = NULL;
+-		}
+-	}
+-	for (i=0; i<MAX_MIXPLUGINS; i++)
+-	{
+-		if ((m_MixPlugins[i].nPluginDataSize) && (m_MixPlugins[i].pPluginData))
+-		{
+-			m_MixPlugins[i].nPluginDataSize = 0;
+-			delete [] (signed char*)m_MixPlugins[i].pPluginData;
+-			m_MixPlugins[i].pPluginData = NULL;
+-		}
+-		m_MixPlugins[i].pMixState = NULL;
+-		if (m_MixPlugins[i].pMixPlugin)
+-		{
+-			m_MixPlugins[i].pMixPlugin->Release();
+-			m_MixPlugins[i].pMixPlugin = NULL;
+-		}
+-	}
+-	m_nType = MOD_TYPE_NONE;
+-	m_nChannels = m_nSamples = m_nInstruments = 0;
+-	return TRUE;
+-}
+-
+-
+-//////////////////////////////////////////////////////////////////////////
+-// Memory Allocation
+-
+-MODCOMMAND *CSoundFile::AllocatePattern(UINT rows, UINT nchns)
+-//------------------------------------------------------------
+-{
+-	MODCOMMAND *p = new MODCOMMAND[rows*nchns];
+-	if (p) memset(p, 0, rows*nchns*sizeof(MODCOMMAND));
+-	return p;
+-}
+-
+-
+-void CSoundFile::FreePattern(LPVOID pat)
+-//--------------------------------------
+-{
+-	if (pat) delete [] (signed char*)pat;
+-}
+-
+-
+-signed char* CSoundFile::AllocateSample(UINT nbytes)
+-//-------------------------------------------
+-{
+-	signed char * p = (signed char *)GlobalAllocPtr(GHND, (nbytes+39) & ~7);
+-	if (p) p += 16;
+-	return p;
+-}
+-
+-
+-void CSoundFile::FreeSample(LPVOID p)
+-//-----------------------------------
+-{
+-	if (p)
+-	{
+-		GlobalFreePtr(((LPSTR)p)-16);
+-	}
+-}
+-
+-
+-//////////////////////////////////////////////////////////////////////////
+-// Misc functions
+-
+-void CSoundFile::ResetMidiCfg()
+-//-----------------------------
+-{
+-	memset(&m_MidiCfg, 0, sizeof(m_MidiCfg));
+-	lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_START*32], "FF");
+-	lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_STOP*32], "FC");
+-	lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_NOTEON*32], "9c n v");
+-	lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_NOTEOFF*32], "9c n 0");
+-	lstrcpy(&m_MidiCfg.szMidiGlb[MIDIOUT_PROGRAM*32], "Cc p");
+-	lstrcpy(&m_MidiCfg.szMidiSFXExt[0], "F0F000z");
+-	for (int iz=0; iz<16; iz++) wsprintf(&m_MidiCfg.szMidiZXXExt[iz*32], "F0F001%02X", iz*8);
+-}
+-
+-
+-UINT CSoundFile::GetNumChannels() const
+-//-------------------------------------
+-{
+-	UINT n = 0;
+-	for (UINT i=0; i<m_nChannels; i++) if (ChnSettings[i].nVolume) n++;
+-	return n;
+-}
+-
+-
+-UINT CSoundFile::GetSongComments(LPSTR s, UINT len, UINT linesize)
+-//----------------------------------------------------------------
+-{
+-	LPCSTR p = m_lpszSongComments;
+-	if (!p) return 0;
+-	UINT i = 2, ln=0;
+-	if ((len) && (s)) s[0] = '\x0D';
+-	if ((len > 1) && (s)) s[1] = '\x0A';
+-	while ((*p)	&& (i+2 < len))
+-	{
+-		BYTE c = (BYTE)*p++;
+-		if ((c == 0x0D) || ((c == ' ') && (ln >= linesize)))
+-			{ if (s) { s[i++] = '\x0D'; s[i++] = '\x0A'; } else i+= 2; ln=0; }
+-		else
+-		if (c >= 0x20) { if (s) s[i++] = c; else i++; ln++; }
+-	}
+-	if (s) s[i] = 0;
+-	return i;
+-}
+-
+-
+-UINT CSoundFile::GetRawSongComments(LPSTR s, UINT len, UINT linesize)
+-//-------------------------------------------------------------------
+-{
+-	LPCSTR p = m_lpszSongComments;
+-	if (!p) return 0;
+-	UINT i = 0, ln=0;
+-	while ((*p)	&& (i < len-1))
+-	{
+-		BYTE c = (BYTE)*p++;
+-		if ((c == 0x0D)	|| (c == 0x0A))
+-		{
+-			if (ln)
+-			{
+-				while (ln < linesize) { if (s) s[i] = ' '; i++; ln++; }
+-				ln = 0;
+-			}
+-		} else
+-		if ((c == ' ') && (!ln))
+-		{
+-			UINT k=0;
+-			while ((p[k]) && (p[k] >= ' '))	k++;
+-			if (k <= linesize)
+-			{
+-				if (s) s[i] = ' ';
+-				i++;
+-				ln++;
+-			}
+-		} else
+-		{
+-			if (s) s[i] = c;
+-			i++;
+-			ln++;
+-			if (ln == linesize) ln = 0;
+-		}
+-	}
+-	if (ln)
+-	{
+-		while ((ln < linesize) && (i < len))
+-		{
+-			if (s) s[i] = ' ';
+-			i++;
+-			ln++;
+-		}
+-	}
+-	if (s) s[i] = 0;
+-	return i;
+-}
+-
+-
+-BOOL CSoundFile::SetWaveConfig(UINT nRate,UINT nBits,UINT nChannels,BOOL bMMX)
+-//----------------------------------------------------------------------------
+-{
+-	BOOL bReset = FALSE;
+-	DWORD d = gdwSoundSetup & ~SNDMIX_ENABLEMMX;
+-	if (bMMX) d |= SNDMIX_ENABLEMMX;
+-	if ((gdwMixingFreq != nRate) || (gnBitsPerSample != nBits) || (gnChannels != nChannels) || (d != gdwSoundSetup)) bReset = TRUE;
+-	gnChannels = nChannels;
+-	gdwSoundSetup = d;
+-	gdwMixingFreq = nRate;
+-	gnBitsPerSample = nBits;
+-	InitPlayer(bReset);
+-//printf("Rate=%u Bits=%u Channels=%u MMX=%u\n",gdwMixingFreq,gnBitsPerSample,gnChannels,bMMX);
+-	return TRUE;
+-}
+-
+-
+-BOOL CSoundFile::SetResamplingMode(UINT nMode)
+-//--------------------------------------------
+-{
+-	DWORD d = gdwSoundSetup & ~(SNDMIX_NORESAMPLING|SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE);
+-	switch(nMode)
+-	{
+-	case SRCMODE_NEAREST:	d |= SNDMIX_NORESAMPLING; break;
+-	case SRCMODE_LINEAR:	break;
+-	case SRCMODE_SPLINE:	d |= SNDMIX_HQRESAMPLER; break;
+-	case SRCMODE_POLYPHASE:	d |= (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); break;
+-	default:
+-		return FALSE;
+-	}
+-	gdwSoundSetup = d;
+-	return TRUE;
+-}
+-
+-
+-BOOL CSoundFile::SetMasterVolume(UINT nVol, BOOL bAdjustAGC)
+-//----------------------------------------------------------
+-{
+-	if (nVol < 1) nVol = 1;
+-	if (nVol > 0x200) nVol = 0x200;	// x4 maximum
+-	if ((gdwSoundSetup & SNDMIX_AGC) && (bAdjustAGC))
+-	{
+-		gnAGC = gnAGC * m_nMasterVolume / nVol;
+-		if (gnAGC > AGC_UNITY) gnAGC = AGC_UNITY;
+-	}
+-	m_nMasterVolume = nVol;
+-	return TRUE;
+-}
+-
+-
+-void CSoundFile::SetAGC(BOOL b)
+-//-----------------------------
+-{
+-	if (b)
+-	{
+-		if (!(gdwSoundSetup & SNDMIX_AGC))
+-		{
+-			gdwSoundSetup |= SNDMIX_AGC;
+-			gnAGC = AGC_UNITY;
+-		}
+-	} else gdwSoundSetup &= ~SNDMIX_AGC;
+-}
+-
+-
+-UINT CSoundFile::GetNumPatterns() const
+-//-------------------------------------
+-{
+-	UINT i = 0;
+-	while ((i < MAX_ORDERS) && (Order[i] < 0xFF)) i++;
+-	return i;
+-}
+-
+-
+-UINT CSoundFile::GetNumInstruments() const
+-//----------------------------------------
+-{
+-	UINT n=0;
+-	for (UINT i=0; i<MAX_INSTRUMENTS; i++) if (Ins[i].pSample) n++;
+-	return n;
+-}
+-
+-
+-UINT CSoundFile::GetMaxPosition() const
+-//-------------------------------------
+-{
+-	UINT max = 0;
+-	UINT i = 0;
+-
+-	while ((i < MAX_ORDERS) && (Order[i] != 0xFF))
+-	{
+-		if (Order[i] < MAX_PATTERNS) max += PatternSize[Order[i]];
+-		i++;
+-	}
+-	return max;
+-}
+-
+-
+-UINT CSoundFile::GetCurrentPos() const
+-//------------------------------------
+-{
+-	UINT pos = 0;
+-
+-	for (UINT i=0; i<m_nCurrentPattern; i++) if (Order[i] < MAX_PATTERNS)
+-		pos += PatternSize[Order[i]];
+-	return pos + m_nRow;
+-}
+-
+-
+-void CSoundFile::SetCurrentPos(UINT nPos)
+-//---------------------------------------
+-{
+-	UINT i, nPattern;
+-
+-	for (i=0; i<MAX_CHANNELS; i++)
+-	{
+-		Chn[i].nNote = Chn[i].nNewNote = Chn[i].nNewIns = 0;
+-		Chn[i].pInstrument = NULL;
+-		Chn[i].pHeader = NULL;
+-		Chn[i].nPortamentoDest = 0;
+-		Chn[i].nCommand = 0;
+-		Chn[i].nPatternLoopCount = 0;
+-		Chn[i].nPatternLoop = 0;
+-		Chn[i].nFadeOutVol = 0;
+-		Chn[i].dwFlags |= CHN_KEYOFF|CHN_NOTEFADE;
+-		Chn[i].nTremorCount = 0;
+-	}
+-	if (!nPos)
+-	{
+-		for (i=0; i<MAX_CHANNELS; i++)
+-		{
+-			Chn[i].nPeriod = 0;
+-			Chn[i].nPos = Chn[i].nLength = 0;
+-			Chn[i].nLoopStart = 0;
+-			Chn[i].nLoopEnd = 0;
+-			Chn[i].nROfs = Chn[i].nLOfs = 0;
+-			Chn[i].pSample = NULL;
+-			Chn[i].pInstrument = NULL;
+-			Chn[i].pHeader = NULL;
+-			Chn[i].nCutOff = 0x7F;
+-			Chn[i].nResonance = 0;
+-			Chn[i].nLeftVol = Chn[i].nRightVol = 0;
+-			Chn[i].nNewLeftVol = Chn[i].nNewRightVol = 0;
+-			Chn[i].nLeftRamp = Chn[i].nRightRamp = 0;
+-			Chn[i].nVolume = 256;
+-			if (i < MAX_BASECHANNELS)
+-			{
+-				Chn[i].dwFlags = ChnSettings[i].dwFlags;
+-				Chn[i].nPan = ChnSettings[i].nPan;
+-				Chn[i].nGlobalVol = ChnSettings[i].nVolume;
+-			} else
+-			{
+-				Chn[i].dwFlags = 0;
+-				Chn[i].nPan = 128;
+-				Chn[i].nGlobalVol = 64;
+-			}
+-		}
+-		m_nGlobalVolume = m_nDefaultGlobalVolume;
+-		m_nMusicSpeed = m_nDefaultSpeed;
+-		m_nMusicTempo = m_nDefaultTempo;
+-	}
+-	m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE);
+-	for (nPattern = 0; nPattern < MAX_ORDERS; nPattern++)
+-	{
+-		UINT ord = Order[nPattern];
+-		if (ord == 0xFE) continue;
+-		if (ord == 0xFF) break;
+-		if (ord < MAX_PATTERNS)
+-		{
+-			if (nPos < (UINT)PatternSize[ord]) break;
+-			nPos -= PatternSize[ord];
+-		}
+-	}
+-	// Buggy position ?
+-	if ((nPattern >= MAX_ORDERS)
+-	 || (Order[nPattern] >= MAX_PATTERNS)
+-	 || (nPos >= PatternSize[Order[nPattern]]))
+-	{
+-		nPos = 0;
+-		nPattern = 0;
+-	}
+-	UINT nRow = nPos;
+-	if ((nRow) && (Order[nPattern] < MAX_PATTERNS))
+-	{
+-		MODCOMMAND *p = Patterns[Order[nPattern]];
+-		if ((p) && (nRow < PatternSize[Order[nPattern]]))
+-		{
+-			BOOL bOk = FALSE;
+-			while ((!bOk) && (nRow > 0))
+-			{
+-				UINT n = nRow * m_nChannels;
+-				for (UINT k=0; k<m_nChannels; k++, n++)
+-				{
+-					if (p[n].note)
+-					{
+-						bOk = TRUE;
+-						break;
+-					}
+-				}
+-				if (!bOk) nRow--;
+-			}
+-		}
+-	}
+-	m_nNextPattern = nPattern;
+-	m_nNextRow = nRow;
+-	m_nTickCount = m_nMusicSpeed;
+-	m_nBufferCount = 0;
+-	m_nPatternDelay = 0;
+-	m_nFrameDelay = 0;
+-}
+-
+-
+-void CSoundFile::SetCurrentOrder(UINT nPos)
+-//-----------------------------------------
+-{
+-	while ((nPos < MAX_ORDERS) && (Order[nPos] == 0xFE)) nPos++;
+-	if ((nPos >= MAX_ORDERS) || (Order[nPos] >= MAX_PATTERNS)) return;
+-	for (UINT j=0; j<MAX_CHANNELS; j++)
+-	{
+-		Chn[j].nPeriod = 0;
+-		Chn[j].nNote = 0;
+-		Chn[j].nPortamentoDest = 0;
+-		Chn[j].nCommand = 0;
+-		Chn[j].nPatternLoopCount = 0;
+-		Chn[j].nPatternLoop = 0;
+-		Chn[j].nTremorCount = 0;
+-	}
+-	if (!nPos)
+-	{
+-		SetCurrentPos(0);
+-	} else
+-	{
+-		m_nNextPattern = nPos;
+-		m_nRow = m_nNextRow = 0;
+-		m_nPattern = 0;
+-		m_nTickCount = m_nMusicSpeed;
+-		m_nBufferCount = 0;
+-		m_nTotalCount = 0;
+-		m_nPatternDelay = 0;
+-		m_nFrameDelay = 0;
+-	}
+-	m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE);
+-}
+-
+-void CSoundFile::ResetChannels()
+-//------------------------------
+-{
+-	m_dwSongFlags &= ~(SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE);
+-	m_nBufferCount = 0;
+-	for (UINT i=0; i<MAX_CHANNELS; i++)
+-	{
+-		Chn[i].nROfs = Chn[i].nLOfs = 0;
+-	}
+-}
+-
+-
+-void CSoundFile::ResetTimestamps()
+-//--------------------------------
+-{
+-	int n;
+-
+-	for (n = 1; n < MAX_SAMPLES; n++) {
+-		Ins[n].played = 0;
+-	}
+-	for (n = 1; n < MAX_INSTRUMENTS; n++) {
+-		if (Headers[n])
+-			Headers[n]->played = 0;
+-	}
+-}
+-
+-
+-void CSoundFile::LoopPattern(int nPat, int nRow)
+-//----------------------------------------------
+-{
+-	if ((nPat < 0) || (nPat >= MAX_PATTERNS) || (!Patterns[nPat]))
+-	{
+-		m_dwSongFlags &= ~SONG_PATTERNLOOP;
+-	} else
+-	{
+-		if ((nRow < 0) || (nRow >= PatternSize[nPat])) nRow = 0;
+-		m_nPattern = nPat;
+-		m_nRow = m_nNextRow = nRow;
+-		m_nTickCount = m_nMusicSpeed;
+-		m_nPatternDelay = 0;
+-		m_nFrameDelay = 0;
+-		m_nBufferCount = 0;
+-		m_dwSongFlags |= SONG_PATTERNLOOP;
+-	}
+-}
+-
+-
+-UINT CSoundFile::GetBestSaveFormat() const
+-//----------------------------------------
+-{
+-	if ((!m_nSamples) || (!m_nChannels)) return MOD_TYPE_NONE;
+-	if (!m_nType) return MOD_TYPE_NONE;
+-	if (m_nType & (MOD_TYPE_MOD|MOD_TYPE_OKT))
+-		return MOD_TYPE_MOD;
+-	if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_STM|MOD_TYPE_ULT|MOD_TYPE_FAR|MOD_TYPE_PTM))
+-		return MOD_TYPE_S3M;
+-	if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MED|MOD_TYPE_MTM|MOD_TYPE_MT2))
+-		return MOD_TYPE_XM;
+-	return MOD_TYPE_IT;
+-}
+-
+-
+-UINT CSoundFile::GetSaveFormats() const
+-//-------------------------------------
+-{
+-	UINT n = 0;
+-	if ((!m_nSamples) || (!m_nChannels) || (m_nType == MOD_TYPE_NONE)) return 0;
+-	switch(m_nType)
+-	{
+-	case MOD_TYPE_MOD:	n = MOD_TYPE_MOD;
+-	case MOD_TYPE_S3M:	n = MOD_TYPE_S3M;
+-	}
+-	n |= MOD_TYPE_XM | MOD_TYPE_IT;
+-	if (!(m_dwSongFlags & SONG_INSTRUMENTMODE))
+-	{
+-		if (m_nSamples < 32) n |= MOD_TYPE_MOD;
+-		n |= MOD_TYPE_S3M;
+-	}
+-	return n;
+-}
+-
+-
+-UINT CSoundFile::GetSampleName(UINT nSample,LPSTR s) const
+-//--------------------------------------------------------
+-{
+-        char sztmp[40] = "";      // changed from CHAR
+-	memcpy(sztmp, m_szNames[nSample],32);
+-	sztmp[31] = 0;
+-	if (s) strcpy(s, sztmp);
+-	return strlen(sztmp);
+-}
+-
+-
+-UINT CSoundFile::GetInstrumentName(UINT nInstr,LPSTR s) const
+-//-----------------------------------------------------------
+-{
+-        char sztmp[40] = "";  // changed from CHAR
+-	if ((nInstr >= MAX_INSTRUMENTS) || (!Headers[nInstr]))
+-	{
+-		if (s) *s = 0;
+-		return 0;
+-	}
+-	INSTRUMENTHEADER *penv = Headers[nInstr];
+-	memcpy(sztmp, penv->name, 32);
+-	sztmp[31] = 0;
+-	if (s) strcpy(s, sztmp);
+-	return strlen(sztmp);
+-}
+-
+-
+-#ifndef NO_PACKING
+-UINT CSoundFile::PackSample(int &sample, int next)
+-//------------------------------------------------
+-{
+-	UINT i = 0;
+-	int delta = next - sample;
+-	if (delta >= 0)
+-	{
+-		for (i=0; i<7; i++) if (delta <= (int)CompressionTable[i+1]) break;
+-	} else
+-	{
+-		for (i=8; i<15; i++) if (delta >= (int)CompressionTable[i+1]) break;
+-	}
+-	sample += (int)CompressionTable[i];
+-	return i;
+-}
+-
+-
+-BOOL CSoundFile::CanPackSample(LPSTR pSample, UINT nLen, UINT nPacking, BYTE *result)
+-//-----------------------------------------------------------------------------------
+-{
+-	int pos, old, oldpos, besttable = 0;
+-	DWORD dwErr, dwTotal, dwResult;
+-	int i,j;
+-
+-	if (result) *result = 0;
+-	if ((!pSample) || (nLen < 1024)) return FALSE;
+-	// Try packing with different tables
+-	dwResult = 0;
+-	for (j=1; j<MAX_PACK_TABLES; j++)
+-	{
+-		memcpy(CompressionTable, UnpackTable[j], 16);
+-		dwErr = 0;
+-		dwTotal = 1;
+-		old = pos = oldpos = 0;
+-		for (i=0; i<(int)nLen; i++)
+-		{
+-			int s = (int)pSample[i];
+-			PackSample(pos, s);
+-			dwErr += abs(pos - oldpos);
+-			dwTotal += abs(s - old);
+-			old = s;
+-			oldpos = pos;
+-		}
+-		dwErr = _muldiv(dwErr, 100, dwTotal);
+-		if (dwErr >= dwResult)
+-		{
+-			dwResult = dwErr;
+-			besttable = j;
+-		}
+-	}
+-	memcpy(CompressionTable, UnpackTable[besttable], 16);
+-	if (result)
+-	{
+-		if (dwResult > 100) *result	= 100; else *result = (BYTE)dwResult;
+-	}
+-	return (dwResult >= nPacking) ? TRUE : FALSE;
+-}
+-#endif // NO_PACKING
+-
+-
+-
+-// Flags:
+-//	0 = signed 8-bit PCM data (default)
+-//	1 = unsigned 8-bit PCM data
+-//	2 = 8-bit ADPCM data with linear table
+-//	3 = 4-bit ADPCM data
+-//	4 = 16-bit ADPCM data with linear table
+-//	5 = signed 16-bit PCM data
+-//	6 = unsigned 16-bit PCM data
+-
+-
+-UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, DWORD dwMemLength)
+-//------------------------------------------------------------------------------------------------
+-{
+-	UINT len = 0, mem = pIns->nLength+6;
+-
+-	if ((!pIns) || (pIns->nLength < 1) || (!lpMemFile)) return 0;
+-	if (pIns->nLength > MAX_SAMPLE_LENGTH) pIns->nLength = MAX_SAMPLE_LENGTH;
+-	pIns->uFlags &= ~(CHN_16BIT|CHN_STEREO);
+-	if (nFlags & RSF_16BIT)
+-	{
+-		mem *= 2;
+-		pIns->uFlags |= CHN_16BIT;
+-	}
+-	if (nFlags & RSF_STEREO)
+-	{
+-		mem *= 2;
+-		pIns->uFlags |= CHN_STEREO;
+-	}
+-	if ((pIns->pSample = AllocateSample(mem)) == NULL)
+-	{
+-		pIns->nLength = 0;
+-		return 0;
+-	}
+-	switch(nFlags)
+-	{
+-	// 1: 8-bit unsigned PCM data
+-	case RS_PCM8U:
+-		{
+-			len = pIns->nLength;
+-			if (len > dwMemLength) len = pIns->nLength = dwMemLength;
+-			signed char *pSample = pIns->pSample;
+-			for (UINT j=0; j<len; j++) pSample[j] = (signed char)(lpMemFile[j] - 0x80);
+-		}
+-		break;
+-
+-	// 2: 8-bit ADPCM data with linear table
+-	case RS_PCM8D:
+-		{
+-			len = pIns->nLength;
+-			if (len > dwMemLength) break;
+-			signed char *pSample = pIns->pSample;
+-			const signed char *p = (const signed char *)lpMemFile;
+-			int delta = 0;
+-
+-			for (UINT j=0; j<len; j++)
+-			{
+-				delta += p[j];
+-				*pSample++ = (signed char)delta;
+-			}
+-		}
+-		break;
+-
+-	// 3: 4-bit ADPCM data
+-	case RS_ADPCM4:
+-		{
+-			len = (pIns->nLength + 1) / 2;
+-			if (len > dwMemLength - 16) break;
+-			memcpy(CompressionTable, lpMemFile, 16);
+-			lpMemFile += 16;
+-			signed char *pSample = pIns->pSample;
+-			signed char delta = 0;
+-			for (UINT j=0; j<len; j++)
+-			{
+-				BYTE b0 = (BYTE)lpMemFile[j];
+-				BYTE b1 = (BYTE)(lpMemFile[j] >> 4);
+-				delta = (signed char)GetDeltaValue((int)delta, b0);
+-				pSample[0] = delta;
+-				delta = (signed char)GetDeltaValue((int)delta, b1);
+-				pSample[1] = delta;
+-				pSample += 2;
+-			}
+-			len += 16;
+-		}
+-		break;
+-
+-	// 4: 16-bit ADPCM data with linear table
+-	case RS_PCM16D:
+-		{
+-			len = pIns->nLength * 2;
+-			if (len > dwMemLength) break;
+-			short *pSample = (short *)pIns->pSample;
+-			short *p = (short *)lpMemFile;
+-			unsigned short tmp;
+-			int delta16 = 0;
+-			for (UINT j=0; j<len; j+=2)
+-			{
+-				tmp = *((unsigned short *)p++);
+-				delta16 += bswapLE16(tmp);
+-				*pSample++ = (short) delta16;
+-			}
+-		}
+-		break;
+-
+-	// 5: 16-bit signed PCM data
+-	case RS_PCM16S:
+-	        {
+-		len = pIns->nLength * 2;
+-		if (len <= dwMemLength) memcpy(pIns->pSample, lpMemFile, len);
+-			short int *pSample = (short int *)pIns->pSample;
+-			for (UINT j=0; j<len; j+=2)
+-			{
+-			        *pSample = bswapLE16(*pSample);
+-				pSample++;
+-			}
+-		}
+-		break;
+-
+-	// 16-bit signed mono PCM motorola byte order
+-	case RS_PCM16M:
+-		len = pIns->nLength * 2;
+-		if (len > dwMemLength) len = dwMemLength & ~1;
+-		if (len > 1)
+-		{
+-			signed char *pSample = (signed char *)pIns->pSample;
+-			signed char *pSrc = (signed char *)lpMemFile;
+-			for (UINT j=0; j<len; j+=2)
+-			{
+-			  	// pSample[j] = pSrc[j+1];
+-				// pSample[j+1] = pSrc[j];
+-			        *((unsigned short *)(pSample+j)) = bswapBE16(*((unsigned short *)(pSrc+j)));
+-			}
+-		}
+-		break;
+-
+-	// 6: 16-bit unsigned PCM data
+-	case RS_PCM16U:
+-	        {
+-			len = pIns->nLength * 2;
+-			if (len <= dwMemLength) memcpy(pIns->pSample, lpMemFile, len);
+-			short int *pSample = (short int *)pIns->pSample;
+-			for (UINT j=0; j<len; j+=2)
+-			{
+-			        *pSample = bswapLE16(*pSample) - 0x8000;
+-				pSample++;
+-			}
+-		}
+-		break;
+-
+-	// 16-bit signed stereo big endian
+-	case RS_STPCM16M:
+-		len = pIns->nLength * 2;
+-		if (len*2 <= dwMemLength)
+-		{
+-			signed char *pSample = (signed char *)pIns->pSample;
+-			signed char *pSrc = (signed char *)lpMemFile;
+-			for (UINT j=0; j<len; j+=2)
+-			{
+-			        // pSample[j*2] = pSrc[j+1];
+-				// pSample[j*2+1] = pSrc[j];
+-				// pSample[j*2+2] = pSrc[j+1+len];
+-				// pSample[j*2+3] = pSrc[j+len];
+-			        *((unsigned short *)(pSample+j*2)) = bswapBE16(*((unsigned short *)(pSrc+j)));
+-				*((unsigned short *)(pSample+j*2+2)) = bswapBE16(*((unsigned short *)(pSrc+j+len)));
+-			}
+-			len *= 2;
+-		}
+-		break;
+-
+-	// 8-bit stereo samples
+-	case RS_STPCM8S:
+-	case RS_STPCM8U:
+-	case RS_STPCM8D:
+-		{
+-			int iadd_l = 0, iadd_r = 0;
+-			if (nFlags == RS_STPCM8U) { iadd_l = iadd_r = -128; }
+-			len = pIns->nLength;
+-			signed char *psrc = (signed char *)lpMemFile;
+-			signed char *pSample = (signed char *)pIns->pSample;
+-			if (len*2 > dwMemLength) break;
+-			for (UINT j=0; j<len; j++)
+-			{
+-				pSample[j*2] = (signed char)(psrc[0] + iadd_l);
+-				pSample[j*2+1] = (signed char)(psrc[len] + iadd_r);
+-				psrc++;
+-				if (nFlags == RS_STPCM8D)
+-				{
+-					iadd_l = pSample[j*2];
+-					iadd_r = pSample[j*2+1];
+-				}
+-			}
+-			len *= 2;
+-		}
+-		break;
+-
+-	// 16-bit stereo samples
+-	case RS_STPCM16S:
+-	case RS_STPCM16U:
+-	case RS_STPCM16D:
+-		{
+-			int iadd_l = 0, iadd_r = 0;
+-			if (nFlags == RS_STPCM16U) { iadd_l = iadd_r = -0x8000; }
+-			len = pIns->nLength;
+-			short int *psrc = (short int *)lpMemFile;
+-			short int *pSample = (short int *)pIns->pSample;
+-			if (len*4 > dwMemLength) break;
+-			for (UINT j=0; j<len; j++)
+-			{
+-				pSample[j*2] = (short int) (bswapLE16(psrc[0]) + iadd_l);
+-				pSample[j*2+1] = (short int) (bswapLE16(psrc[len]) + iadd_r);
+-				psrc++;
+-				if (nFlags == RS_STPCM16D)
+-				{
+-					iadd_l = pSample[j*2];
+-					iadd_r = pSample[j*2+1];
+-				}
+-			}
+-			len *= 4;
+-		}
+-		break;
+-
+-	// IT 2.14 compressed samples
+-	case RS_IT2148:
+-	case RS_IT21416:
+-	case RS_IT2158:
+-	case RS_IT21516:
+-		len = dwMemLength;
+-		if (len < 2) break;
+-		if ((nFlags == RS_IT2148) || (nFlags == RS_IT2158))
+-			ITUnpack8Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT2158));
+-		else
+-			ITUnpack16Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT21516));
+-		break;
+-
+-#ifndef MODPLUG_FASTSOUNDLIB
+-	// 8-bit interleaved stereo samples
+-	case RS_STIPCM8S:
+-	case RS_STIPCM8U:
+-		{
+-			int iadd = 0;
+-			if (nFlags == RS_STIPCM8U) { iadd = -0x80; }
+-			len = pIns->nLength;
+-			if (len*2 > dwMemLength) len = dwMemLength >> 1;
+-			LPBYTE psrc = (LPBYTE)lpMemFile;
+-			LPBYTE pSample = (LPBYTE)pIns->pSample;
+-			for (UINT j=0; j<len; j++)
+-			{
+-				pSample[j*2] = (signed char)(psrc[0] + iadd);
+-				pSample[j*2+1] = (signed char)(psrc[1] + iadd);
+-				psrc+=2;
+-			}
+-			len *= 2;
+-		}
+-		break;
+-
+-	// 16-bit interleaved stereo samples
+-	case RS_STIPCM16S:
+-	case RS_STIPCM16U:
+-		{
+-			int iadd = 0;
+-			if (nFlags == RS_STIPCM16U) iadd = -32768;
+-			len = pIns->nLength;
+-			if (len*4 > dwMemLength) len = dwMemLength >> 2;
+-			short int *psrc = (short int *)lpMemFile;
+-			short int *pSample = (short int *)pIns->pSample;
+-			for (UINT j=0; j<len; j++)
+-			{
+-				pSample[j*2] = (short int)(bswapLE16(psrc[0]) + iadd);
+-				pSample[j*2+1] = (short int)(bswapLE16(psrc[1]) + iadd);
+-				psrc += 2;
+-			}
+-			len *= 4;
+-		}
+-		break;
+-
+-	// AMS compressed samples
+-	case RS_AMS8:
+-	case RS_AMS16:
+-		len = 9;
+-		if (dwMemLength > 9)
+-		{
+-			const char *psrc = lpMemFile;
+-			char packcharacter = lpMemFile[8], *pdest = (char *)pIns->pSample;
+-			len += bswapLE32(*((LPDWORD)(lpMemFile+4)));
+-			if (len > dwMemLength) len = dwMemLength;
+-			UINT dmax = pIns->nLength;
+-			if (pIns->uFlags & CHN_16BIT) dmax <<= 1;
+-			AMSUnpack(psrc+9, len-9, pdest, dmax, packcharacter);
+-		}
+-		break;
+-
+-	// PTM 8bit delta to 16-bit sample
+-	case RS_PTM8DTO16:
+-		{
+-			len = pIns->nLength * 2;
+-			if (len > dwMemLength) break;
+-			signed char *pSample = (signed char *)pIns->pSample;
+-			signed char delta8 = 0;
+-			for (UINT j=0; j<len; j++)
+-			{
+-				delta8 += lpMemFile[j];
+-				*pSample++ = delta8;
+-			}
+-			WORD *pSampleW = (WORD *)pIns->pSample;
+-			for (UINT j=0; j<len; j+=2)   // swaparoni!
+-			{
+-				*pSampleW = bswapLE16(*pSampleW);
+-				pSampleW++;
+-			}
+-		}
+-		break;
+-
+-	// Huffman MDL compressed samples
+-	case RS_MDL8:
+-	case RS_MDL16:
+-		len = dwMemLength;
+-		if (len >= 4)
+-		{
+-			LPBYTE pSample = (LPBYTE)pIns->pSample;
+-			LPBYTE ibuf = (LPBYTE)lpMemFile;
+-			DWORD bitbuf = bswapLE32(*((DWORD *)ibuf));
+-			UINT bitnum = 32;
+-			BYTE dlt = 0, lowbyte = 0;
+-			ibuf += 4;
+-			for (UINT j=0; j<pIns->nLength; j++)
+-			{
+-				BYTE hibyte;
+-				BYTE sign;
+-				if (nFlags == RS_MDL16) lowbyte = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 8);
+-				sign = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 1);
+-				if (MDLReadBits(bitbuf, bitnum, ibuf, 1))
+-				{
+-					hibyte = (BYTE)MDLReadBits(bitbuf, bitnum, ibuf, 3);
+-				} else
+-				{
+-					hibyte = 8;
+-					while (!MDLReadBits(bitbuf, bitnum, ibuf, 1)) hibyte += 0x10;
+-					hibyte += MDLReadBits(bitbuf, bitnum, ibuf, 4);
+-				}
+-				if (sign) hibyte = ~hibyte;
+-				dlt += hibyte;
+-				if (nFlags != RS_MDL16)
+-					pSample[j] = dlt;
+-				else
+-				{
+-					pSample[j<<1] = lowbyte;
+-					pSample[(j<<1)+1] = dlt;
+-				}
+-			}
+-		}
+-		break;
+-
+-	case RS_DMF8:
+-	case RS_DMF16:
+-		len = dwMemLength;
+-		if (len >= 4)
+-		{
+-			UINT maxlen = pIns->nLength;
+-			if (pIns->uFlags & CHN_16BIT) maxlen <<= 1;
+-			LPBYTE ibuf = (LPBYTE)lpMemFile, ibufmax = (LPBYTE)(lpMemFile+dwMemLength);
+-			len = DMFUnpack((LPBYTE)pIns->pSample, ibuf, ibufmax, maxlen);
+-		}
+-		break;
+-
+-#ifdef MODPLUG_TRACKER
+-	// PCM 24-bit signed -> load sample, and normalize it to 16-bit
+-	case RS_PCM24S:
+-	case RS_PCM32S:
+-		len = pIns->nLength * 3;
+-		if (nFlags == RS_PCM32S) len += pIns->nLength;
+-		if (len > dwMemLength) break;
+-		if (len > 4*8)
+-		{
+-			UINT slsize = (nFlags == RS_PCM32S) ? 4 : 3;
+-			LPBYTE pSrc = (LPBYTE)lpMemFile;
+-			LONG max = 255;
+-			if (nFlags == RS_PCM32S) pSrc++;
+-			for (UINT j=0; j<len; j+=slsize)
+-			{
+-				LONG l = ((((pSrc[j+2] << 8) + pSrc[j+1]) << 8) + pSrc[j]) << 8;
+-				l /= 256;
+-				if (l > max) max = l;
+-				if (-l > max) max = -l;
+-			}
+-			max = (max / 128) + 1;
+-			signed short *pDest = (signed short *)pIns->pSample;
+-			for (UINT k=0; k<len; k+=slsize)
+-			{
+-				LONG l = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8;
+-				*pDest++ = (signed short)(l / max);
+-			}
+-		}
+-		break;
+-
+-	// Stereo PCM 24-bit signed -> load sample, and normalize it to 16-bit
+-	case RS_STIPCM24S:
+-	case RS_STIPCM32S:
+-		len = pIns->nLength * 6;
+-		if (nFlags == RS_STIPCM32S) len += pIns->nLength * 2;
+-		if (len > dwMemLength) break;
+-		if (len > 8*8)
+-		{
+-			UINT slsize = (nFlags == RS_STIPCM32S) ? 4 : 3;
+-			LPBYTE pSrc = (LPBYTE)lpMemFile;
+-			LONG max = 255;
+-			if (nFlags == RS_STIPCM32S) pSrc++;
+-			for (UINT j=0; j<len; j+=slsize)
+-			{
+-				LONG l = ((((pSrc[j+2] << 8) + pSrc[j+1]) << 8) + pSrc[j]) << 8;
+-				l /= 256;
+-				if (l > max) max = l;
+-				if (-l > max) max = -l;
+-			}
+-			max = (max / 128) + 1;
+-			signed short *pDest = (signed short *)pIns->pSample;
+-			for (UINT k=0; k<len; k+=slsize)
+-			{
+-				LONG lr = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8;
+-				k += slsize;
+-				LONG ll = ((((pSrc[k+2] << 8) + pSrc[k+1]) << 8) + pSrc[k]) << 8;
+-				pDest[0] = (signed short)ll;
+-				pDest[1] = (signed short)lr;
+-				pDest += 2;
+-			}
+-		}
+-		break;
+-
+-	// 16-bit signed big endian interleaved stereo
+-	case RS_STIPCM16M:
+-		{
+-			len = pIns->nLength;
+-			if (len*4 > dwMemLength) len = dwMemLength >> 2;
+-			LPCBYTE psrc = (LPCBYTE)lpMemFile;
+-			short int *pSample = (short int *)pIns->pSample;
+-			for (UINT j=0; j<len; j++)
+-			{
+-				pSample[j*2] = (signed short)(((UINT)psrc[0] << 8) | (psrc[1]));
+-				pSample[j*2+1] = (signed short)(((UINT)psrc[2] << 8) | (psrc[3]));
+-				psrc += 4;
+-			}
+-			len *= 4;
+-		}
+-		break;
+-
+-#endif // MODPLUG_TRACKER
+-#endif // !MODPLUG_FASTSOUNDLIB
+-
+-	// Default: 8-bit signed PCM data
+-	default:
+-		len = pIns->nLength;
+-		if (len > dwMemLength) len = pIns->nLength = dwMemLength;
+-		memcpy(pIns->pSample, lpMemFile, len);
+-	}
+-	if (len > dwMemLength)
+-	{
+-		if (pIns->pSample)
+-		{
+-			pIns->nLength = 0;
+-			FreeSample(pIns->pSample);
+-			pIns->pSample = NULL;
+-		}
+-		return 0;
+-	}
+-	AdjustSampleLoop(pIns);
+-	return len;
+-}
+-
+-
+-void CSoundFile::AdjustSampleLoop(MODINSTRUMENT *pIns)
+-//----------------------------------------------------
+-{
+-	if (!pIns->pSample) return;
+-	if (pIns->nLoopEnd > pIns->nLength) pIns->nLoopEnd = pIns->nLength;
+-	if (pIns->nLoopStart+2 >= pIns->nLoopEnd)
+-	{
+-		pIns->nLoopStart = pIns->nLoopEnd = 0;
+-		pIns->uFlags &= ~CHN_LOOP;
+-	}
+-	UINT len = pIns->nLength;
+-	if (pIns->uFlags & CHN_16BIT)
+-	{
+-		short int *pSample = (short int *)pIns->pSample;
+-		// Adjust end of sample
+-		if (pIns->uFlags & CHN_STEREO)
+-		{
+-			pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2];
+-			pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1];
+-		} else
+-		{
+-			pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1];
+-		}
+-		if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP)
+-		{
+-			// Fix bad loops
+-			if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & MOD_TYPE_S3M))
+-			{
+-				pSample[pIns->nLoopEnd] = pSample[pIns->nLoopStart];
+-				pSample[pIns->nLoopEnd+1] = pSample[pIns->nLoopStart+1];
+-				pSample[pIns->nLoopEnd+2] = pSample[pIns->nLoopStart+2];
+-				pSample[pIns->nLoopEnd+3] = pSample[pIns->nLoopStart+3];
+-				pSample[pIns->nLoopEnd+4] = pSample[pIns->nLoopStart+4];
+-			}
+-		}
+-	} else
+-	{
+-		signed char *pSample = pIns->pSample;
+-#ifndef MODPLUG_FASTSOUNDLIB
+-		// Crappy samples (except chiptunes) ?
+-		if ((pIns->nLength > 0x100) && (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M))
+-		 && (!(pIns->uFlags & CHN_STEREO)))
+-		{
+-			int smpend = pSample[pIns->nLength-1], smpfix = 0, kscan;
+-			for (kscan=pIns->nLength-1; kscan>0; kscan--)
+-			{
+-				smpfix = pSample[kscan-1];
+-				if (smpfix != smpend) break;
+-			}
+-			int delta = smpfix - smpend;
+-			if (((!(pIns->uFlags & CHN_LOOP)) || (kscan > (int)pIns->nLoopEnd))
+-			 && ((delta < -8) || (delta > 8)))
+-			{
+-				while (kscan<(int)pIns->nLength)
+-				{
+-					if (!(kscan & 7))
+-					{
+-						if (smpfix > 0) smpfix--;
+-						if (smpfix < 0) smpfix++;
+-					}
+-					pSample[kscan] = (signed char)smpfix;
+-					kscan++;
+-				}
+-			}
+-		}
+-#endif
+-		// Adjust end of sample
+-		if (pIns->uFlags & CHN_STEREO)
+-		{
+-			pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2];
+-			pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1];
+-		} else
+-		{
+-			pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1];
+-		}
+-		if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP)
+-		{
+-			if ((pIns->nLoopEnd+3 >= pIns->nLength) || (m_nType & (MOD_TYPE_MOD|MOD_TYPE_S3M)))
+-			{
+-				pSample[pIns->nLoopEnd] = pSample[pIns->nLoopStart];
+-				pSample[pIns->nLoopEnd+1] = pSample[pIns->nLoopStart+1];
+-				pSample[pIns->nLoopEnd+2] = pSample[pIns->nLoopStart+2];
+-				pSample[pIns->nLoopEnd+3] = pSample[pIns->nLoopStart+3];
+-				pSample[pIns->nLoopEnd+4] = pSample[pIns->nLoopStart+4];
+-			}
+-		}
+-	}
+-}
+-
+-
+-/////////////////////////////////////////////////////////////
+-// Transpose <-> Frequency conversions
+-
+-// returns 8363*2^((transp*128+ftune)/(12*128))
+-DWORD CSoundFile::TransposeToFrequency(int transp, int ftune)
+-//-----------------------------------------------------------
+-{
+-	//---GCCFIX:  Removed assembly.
+-#ifdef MSC_VER
+-	const float _fbase = 8363;
+-	const float _factor = 1.0f/(12.0f*128.0f);
+-	int result;
+-	DWORD freq;
+-
+-	transp = (transp << 7) + ftune;
+-	_asm {
+-	fild transp
+-	fld _factor
+-	fmulp st(1), st(0)
+-	fist result
+-	fisub result
+-	f2xm1
+-	fild result
+-	fld _fbase
+-	fscale
+-	fstp st(1)
+-	fmul st(1), st(0)
+-	faddp st(1), st(0)
+-	fistp freq
+-	}
+-	UINT derr = freq % 11025;
+-	if (derr <= 8) freq -= derr;
+-	if (derr >= 11015) freq += 11025-derr;
+-	derr = freq % 1000;
+-	if (derr <= 5) freq -= derr;
+-	if (derr >= 995) freq += 1000-derr;
+-	return freq;
+-#else
+-        return (DWORD) (8363.0 * pow(2, (transp * 128.0 + ftune) / 1536.0));
+-#endif
+-}
+-
+-
+-// returns 12*128*log2(freq/8363)
+-int CSoundFile::FrequencyToTranspose(DWORD freq)
+-//----------------------------------------------
+-{
+-	//---GCCFIX:  Removed assembly.
+-#ifdef MSC_VER
+-	const float _f1_8363 = 1.0f / 8363.0f;
+-	const float _factor = 128 * 12;
+-	LONG result;
+-
+-	if (!freq) return 0;
+-	_asm {
+-	fld _factor
+-	fild freq
+-	fld _f1_8363
+-	fmulp st(1), st(0)
+-	fyl2x
+-	fistp result
+-	}
+-	return result;
+-#else
+-	return (int) (1536.0 * (log(freq / 8363.0) / log(2)));
+-#endif
+-}
+-
+-
+-void CSoundFile::FrequencyToTranspose(MODINSTRUMENT *psmp)
+-//--------------------------------------------------------
+-{
+-	int f2t = FrequencyToTranspose(psmp->nC4Speed);
+-	int transp = f2t >> 7;
+-	int ftune = f2t & 0x7F;
+-	if (ftune > 80)
+-	{
+-		transp++;
+-		ftune -= 128;
+-	}
+-	if (transp > 127) transp = 127;
+-	if (transp < -127) transp = -127;
+-	psmp->RelativeTone = transp;
+-	psmp->nFineTune = ftune;
+-}
+-
+-
+-void CSoundFile::CheckCPUUsage(UINT nCPU)
+-//---------------------------------------
+-{
+-	if (nCPU > 100) nCPU = 100;
+-	gnCPUUsage = nCPU;
+-	if (nCPU < 90)
+-	{
+-		m_dwSongFlags &= ~SONG_CPUVERYHIGH;
+-	} else
+-	if ((m_dwSongFlags & SONG_CPUVERYHIGH) && (nCPU >= 94))
+-	{
+-		UINT i=MAX_CHANNELS;
+-		while (i >= 8)
+-		{
+-			i--;
+-			if (Chn[i].nLength)
+-			{
+-				Chn[i].nLength = Chn[i].nPos = 0;
+-				nCPU -= 2;
+-				if (nCPU < 94) break;
+-			}
+-		}
+-	} else
+-	if (nCPU > 90)
+-	{
+-		m_dwSongFlags |= SONG_CPUVERYHIGH;
+-	}
+-}
+-
+-
+-BOOL CSoundFile::SetPatternName(UINT nPat, LPCSTR lpszName)
+-//---------------------------------------------------------
+-{
+-        char szName[MAX_PATTERNNAME] = "";   // changed from CHAR
+-	if (nPat >= MAX_PATTERNS) return FALSE;
+-	if (lpszName) lstrcpyn(szName, lpszName, MAX_PATTERNNAME);
+-	szName[MAX_PATTERNNAME-1] = 0;
+-	if (!m_lpszPatternNames) m_nPatternNames = 0;
+-	if (nPat >= m_nPatternNames)
+-	{
+-		if (!lpszName[0]) return TRUE;
+-		UINT len = (nPat+1)*MAX_PATTERNNAME;
+-		char *p = new char[len];   // changed from CHAR
+-		if (!p) return FALSE;
+-		memset(p, 0, len);
+-		if (m_lpszPatternNames)
+-		{
+-			memcpy(p, m_lpszPatternNames, m_nPatternNames * MAX_PATTERNNAME);
+-			delete m_lpszPatternNames;
+-			m_lpszPatternNames = NULL;
+-		}
+-		m_lpszPatternNames = p;
+-		m_nPatternNames = nPat + 1;
+-	}
+-	memcpy(m_lpszPatternNames + nPat * MAX_PATTERNNAME, szName, MAX_PATTERNNAME);
+-	return TRUE;
+-}
+-
+-
+-BOOL CSoundFile::GetPatternName(UINT nPat, LPSTR lpszName, UINT cbSize) const
+-//---------------------------------------------------------------------------
+-{
+-	if ((!lpszName) || (!cbSize)) return FALSE;
+-	lpszName[0] = 0;
+-	if (cbSize > MAX_PATTERNNAME) cbSize = MAX_PATTERNNAME;
+-	if ((m_lpszPatternNames) && (nPat < m_nPatternNames))
+-	{
+-		memcpy(lpszName, m_lpszPatternNames + nPat * MAX_PATTERNNAME, cbSize);
+-		lpszName[cbSize-1] = 0;
+-		return TRUE;
+-	}
+-	return FALSE;
+-}
+-
+-UINT CSoundFile::GetHighestUsedChannel()
+-//------------------------------
+-{
+-	UINT highchan = 0;
+-
+-	for (UINT ipat=0; ipat<MAX_PATTERNS; ipat++)
+-	{
+-		MODCOMMAND *p = Patterns[ipat];
+-		if (p)
+-		{
+-			UINT jmax = PatternSize[ipat] * m_nChannels;
+-			for (UINT j=0; j<jmax; j++, p++)
+-			{
+-				if ((p->note) && (p->note <= 120))
+-				{
+-					if ((j % m_nChannels) > highchan)
+-						highchan = j % m_nChannels;
+-				}
+-			}
+-		}
+-	}
+-
+-	return highchan;
+-}
+-
+-
+-
+-#ifndef MODPLUG_FASTSOUNDLIB
+-
+-UINT CSoundFile::DetectUnusedSamples(BOOL *pbIns)
+-//-----------------------------------------------
+-{
+-	UINT nExt = 0;
+-
+-	if (!pbIns) return 0;
+-	if (m_dwSongFlags & SONG_INSTRUMENTMODE)
+-	{
+-		memset(pbIns, 0, MAX_SAMPLES * sizeof(BOOL));
+-		for (UINT ipat=0; ipat<MAX_PATTERNS; ipat++)
+-		{
+-			MODCOMMAND *p = Patterns[ipat];
+-			if (p)
+-			{
+-				UINT jmax = PatternSize[ipat] * m_nChannels;
+-				for (UINT j=0; j<jmax; j++, p++)
+-				{
+-					if ((p->note) && (p->note <= 120))
+-					{
+-						if ((p->instr) && (p->instr < MAX_INSTRUMENTS))
+-						{
+-							INSTRUMENTHEADER *penv = Headers[p->instr];
+-							if (penv)
+-							{
+-								UINT n = penv->Keyboard[p->note-1];
+-								if (n < MAX_SAMPLES) pbIns[n] = TRUE;
+-							}
+-						} else
+-						{
+-							for (UINT k=1; k<=m_nInstruments; k++)
+-							{
+-								INSTRUMENTHEADER *penv = Headers[k];
+-								if (penv)
+-								{
+-									UINT n = penv->Keyboard[p->note-1];
+-									if (n < MAX_SAMPLES) pbIns[n] = TRUE;
+-								}
+-							}
+-						}
+-					}
+-				}
+-			}
+-		}
+-		for (UINT ichk=1; ichk<=m_nSamples; ichk++)
+-		{
+-			if ((!pbIns[ichk]) && (Ins[ichk].pSample)) nExt++;
+-		}
+-	}
+-	return nExt;
+-}
+-
+-
+-BOOL CSoundFile::RemoveSelectedSamples(BOOL *pbIns)
+-//-------------------------------------------------
+-{
+-	if (!pbIns) return FALSE;
+-	for (UINT j=1; j<MAX_SAMPLES; j++)
+-	{
+-		if ((!pbIns[j]) && (Ins[j].pSample))
+-		{
+-			DestroySample(j);
+-			if ((j == m_nSamples) && (j > 1)) m_nSamples--;
+-		}
+-	}
+-	return TRUE;
+-}
+-
+-
+-BOOL CSoundFile::DestroySample(UINT nSample)
+-//------------------------------------------
+-{
+-	if ((!nSample) || (nSample >= MAX_SAMPLES)) return FALSE;
+-	if (!Ins[nSample].pSample) return TRUE;
+-	MODINSTRUMENT *pins = &Ins[nSample];
+-	signed char *pSample = pins->pSample;
+-	pins->pSample = NULL;
+-	pins->nLength = 0;
+-	pins->uFlags &= ~(CHN_16BIT);
+-	for (UINT i=0; i<MAX_CHANNELS; i++)
+-	{
+-		if (Chn[i].pSample == pSample)
+-		{
+-			Chn[i].nPos = Chn[i].nLength = 0;
+-			Chn[i].pSample = Chn[i].pCurrentSample = NULL;
+-		}
+-	}
+-	FreeSample(pSample);
+-	return TRUE;
+-}
+-
+-#endif // MODPLUG_FASTSOUNDLIB
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/sndfile.h audacious-plugins-2.5.4/src/modplug/sndfile.h
+--- audacious-plugins-2.5.4-orig/src/modplug/sndfile.h	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/sndfile.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,1042 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>,
+- *          Adam Goode       <adam at evdebs.org> (endian and char fixes for PPC)
+-*/
+-
+-#include <config.h>
+-
+-#ifndef __SNDFILE_H
+-#define __SNDFILE_H
+-
+-#define MODPLUG_TRACKER	1
+-#define MODPLUG_PLAYER	1
+-
+-#ifdef UNDER_CE
+-int _strnicmp(const char *str1,const char *str2, int n);
+-#endif
+-
+-#ifndef LPCBYTE
+-typedef const BYTE * LPCBYTE;
+-#endif
+-
+-#define MOD_AMIGAC2			0x1AB
+-#define MAX_SAMPLE_LENGTH	16000000
+-#define MAX_SAMPLE_RATE		192000
+-#define MAX_ORDERS			256
+-#define MAX_PATTERNS		240
+-#define MAX_SAMPLES			240
+-#define MAX_INSTRUMENTS		MAX_SAMPLES
+-#ifdef MODPLUG_FASTSOUNDLIB
+-#define MAX_CHANNELS		80
+-#else
+-#define MAX_CHANNELS		256
+-#endif
+-#define MAX_BASECHANNELS	64
+-#define MAX_ENVPOINTS		32
+-#define MIN_PERIOD			0x0020
+-#define MAX_PERIOD			0xFFFF
+-#define MAX_PATTERNNAME		32
+-#define MAX_CHANNELNAME		20
+-#define MAX_INFONAME		80
+-#define MAX_EQ_BANDS		6
+-#define MAX_MIXPLUGINS		8
+-
+-
+-#define MOD_TYPE_NONE		0x00
+-#define MOD_TYPE_MOD		0x01
+-#define MOD_TYPE_S3M		0x02
+-#define MOD_TYPE_XM			0x04
+-#define MOD_TYPE_MED		0x08
+-#define MOD_TYPE_MTM		0x10
+-#define MOD_TYPE_IT			0x20
+-#define MOD_TYPE_669		0x40
+-#define MOD_TYPE_ULT		0x80
+-#define MOD_TYPE_STM		0x100
+-#define MOD_TYPE_FAR		0x200
+-#define MOD_TYPE_WAV		0x400
+-#define MOD_TYPE_AMF		0x800
+-#define MOD_TYPE_AMS		0x1000
+-#define MOD_TYPE_DSM		0x2000
+-#define MOD_TYPE_MDL		0x4000
+-#define MOD_TYPE_OKT		0x8000
+-#define MOD_TYPE_MID		0x10000
+-#define MOD_TYPE_DMF		0x20000
+-#define MOD_TYPE_PTM		0x40000
+-#define MOD_TYPE_DBM		0x80000
+-#define MOD_TYPE_MT2		0x100000
+-#define MOD_TYPE_AMF0		0x200000
+-#define MOD_TYPE_PSM		0x400000
+-#define MOD_TYPE_UMX		0x80000000 // Fake type
+-#define MAX_MODTYPE		23
+-
+-
+-
+-// Channel flags:
+-// Bits 0-7:	Sample Flags
+-#define CHN_16BIT               0x01
+-#define CHN_LOOP                0x02
+-#define CHN_PINGPONGLOOP        0x04
+-#define CHN_SUSTAINLOOP         0x08
+-#define CHN_PINGPONGSUSTAIN     0x10
+-#define CHN_PANNING             0x20
+-#define CHN_STEREO              0x40
+-#define CHN_PINGPONGFLAG	0x80
+-// Bits 8-31:	Channel Flags
+-#define CHN_MUTE                0x100
+-#define CHN_KEYOFF              0x200
+-#define CHN_NOTEFADE		0x400
+-#define CHN_SURROUND            0x800
+-#define CHN_NOIDO               0x1000
+-#define CHN_HQSRC               0x2000
+-#define CHN_FILTER              0x4000
+-#define CHN_VOLUMERAMP		0x8000
+-#define CHN_VIBRATO             0x10000
+-#define CHN_TREMOLO             0x20000
+-#define CHN_PANBRELLO		0x40000
+-#define CHN_PORTAMENTO		0x80000
+-#define CHN_GLISSANDO		0x100000
+-#define CHN_VOLENV              0x200000
+-#define CHN_PANENV              0x400000
+-#define CHN_PITCHENV		0x800000
+-#define CHN_FASTVOLRAMP		0x1000000
+-#define CHN_EXTRALOUD		0x2000000
+-#define CHN_REVERB              0x4000000
+-#define CHN_NOREVERB		0x8000000
+-// used to turn off mute but have it reset later
+-#define CHN_NNAMUTE		0x10000000
+-
+-
+-#define ENV_VOLUME              0x0001
+-#define ENV_VOLSUSTAIN		0x0002
+-#define ENV_VOLLOOP             0x0004
+-#define ENV_PANNING             0x0008
+-#define ENV_PANSUSTAIN		0x0010
+-#define ENV_PANLOOP             0x0020
+-#define ENV_PITCH               0x0040
+-#define ENV_PITCHSUSTAIN	0x0080
+-#define ENV_PITCHLOOP		0x0100
+-#define ENV_SETPANNING		0x0200
+-#define ENV_FILTER              0x0400
+-#define ENV_VOLCARRY		0x0800
+-#define ENV_PANCARRY		0x1000
+-#define ENV_PITCHCARRY		0x2000
+-#define ENV_MUTE		0x4000
+-
+-#define CMD_NONE                        0
+-#define CMD_ARPEGGIO			1
+-#define CMD_PORTAMENTOUP		2
+-#define CMD_PORTAMENTODOWN		3
+-#define CMD_TONEPORTAMENTO		4
+-#define CMD_VIBRATO                     5
+-#define CMD_TONEPORTAVOL		6
+-#define CMD_VIBRATOVOL			7
+-#define CMD_TREMOLO                     8
+-#define CMD_PANNING8			9
+-#define CMD_OFFSET                      10
+-#define CMD_VOLUMESLIDE			11
+-#define CMD_POSITIONJUMP		12
+-#define CMD_VOLUME                      13
+-#define CMD_PATTERNBREAK		14
+-#define CMD_RETRIG                      15
+-#define CMD_SPEED                       16
+-#define CMD_TEMPO                       17
+-#define CMD_TREMOR                      18
+-#define CMD_MODCMDEX			19
+-#define CMD_S3MCMDEX			20
+-#define CMD_CHANNELVOLUME		21
+-#define CMD_CHANNELVOLSLIDE		22
+-#define CMD_GLOBALVOLUME		23
+-#define CMD_GLOBALVOLSLIDE		24
+-#define CMD_KEYOFF                      25
+-#define CMD_FINEVIBRATO			26
+-#define CMD_PANBRELLO			27
+-#define CMD_XFINEPORTAUPDOWN            28
+-#define CMD_PANNINGSLIDE		29
+-#define CMD_SETENVPOSITION		30
+-#define CMD_MIDI                        31
+-
+-
+-// Volume Column commands
+-#define VOLCMD_VOLUME			1
+-#define VOLCMD_PANNING			2
+-#define VOLCMD_VOLSLIDEUP		3
+-#define VOLCMD_VOLSLIDEDOWN		4
+-#define VOLCMD_FINEVOLUP		5
+-#define VOLCMD_FINEVOLDOWN		6
+-#define VOLCMD_VIBRATOSPEED		7
+-#define VOLCMD_VIBRATO			8
+-#define VOLCMD_PANSLIDELEFT		9
+-#define VOLCMD_PANSLIDERIGHT	        10
+-#define VOLCMD_TONEPORTAMENTO	        11
+-#define VOLCMD_PORTAUP			12
+-#define VOLCMD_PORTADOWN		13
+-
+-#define RSF_16BIT		0x04
+-#define RSF_STEREO		0x08
+-
+-#define RS_PCM8S		0	// 8-bit signed
+-#define RS_PCM8U		1	// 8-bit unsigned
+-#define RS_PCM8D		2	// 8-bit delta values
+-#define RS_ADPCM4		3	// 4-bit ADPCM-packed
+-#define RS_PCM16D		4	// 16-bit delta values
+-#define RS_PCM16S		5	// 16-bit signed
+-#define RS_PCM16U		6	// 16-bit unsigned
+-#define RS_PCM16M		7	// 16-bit motorola order
+-#define RS_STPCM8S		(RS_PCM8S|RSF_STEREO)  // stereo 8-bit signed
+-#define RS_STPCM8U		(RS_PCM8U|RSF_STEREO)  // stereo 8-bit unsigned
+-#define RS_STPCM8D		(RS_PCM8D|RSF_STEREO)  // stereo 8-bit delta values
+-#define RS_STPCM16S		(RS_PCM16S|RSF_STEREO) // stereo 16-bit signed
+-#define RS_STPCM16U		(RS_PCM16U|RSF_STEREO) // stereo 16-bit unsigned
+-#define RS_STPCM16D		(RS_PCM16D|RSF_STEREO) // stereo 16-bit delta values
+-#define RS_STPCM16M		(RS_PCM16M|RSF_STEREO) // stereo 16-bit signed big endian
+-// IT 2.14 compressed samples
+-#define RS_IT2148		0x10
+-#define RS_IT21416		0x14
+-#define RS_IT2158		0x12
+-#define RS_IT21516		0x16
+-// AMS Packed Samples
+-#define RS_AMS8			0x11
+-#define RS_AMS16		0x15
+-// DMF Huffman compression
+-#define RS_DMF8			0x13
+-#define RS_DMF16		0x17
+-// MDL Huffman compression
+-#define RS_MDL8			0x20
+-#define RS_MDL16		0x24
+-#define RS_PTM8DTO16	0x25
+-// Stereo Interleaved Samples
+-#define RS_STIPCM8S		(RS_PCM8S|0x40|RSF_STEREO)	// stereo 8-bit signed
+-#define RS_STIPCM8U		(RS_PCM8U|0x40|RSF_STEREO)	// stereo 8-bit unsigned
+-#define RS_STIPCM16S	(RS_PCM16S|0x40|RSF_STEREO)	// stereo 16-bit signed
+-#define RS_STIPCM16U	(RS_PCM16U|0x40|RSF_STEREO)	// stereo 16-bit unsigned
+-#define RS_STIPCM16M	(RS_PCM16M|0x40|RSF_STEREO)	// stereo 16-bit signed big endian
+-// 24-bit signed
+-#define RS_PCM24S		(RS_PCM16S|0x80)			// mono 24-bit signed
+-#define RS_STIPCM24S	(RS_PCM16S|0x80|RSF_STEREO)	// stereo 24-bit signed
+-#define RS_PCM32S		(RS_PCM16S|0xC0)			// mono 24-bit signed
+-#define RS_STIPCM32S	(RS_PCM16S|0xC0|RSF_STEREO)	// stereo 24-bit signed
+-
+-// NNA types
+-#define NNA_NOTECUT		0
+-#define NNA_CONTINUE	1
+-#define NNA_NOTEOFF		2
+-#define NNA_NOTEFADE	3
+-
+-// DCT types
+-#define DCT_NONE		0
+-#define DCT_NOTE		1
+-#define DCT_SAMPLE		2
+-#define DCT_INSTRUMENT	3
+-
+-// DNA types
+-#define DNA_NOTECUT		0
+-#define DNA_NOTEOFF		1
+-#define DNA_NOTEFADE	2
+-
+-// Mixer Hardware-Dependent features
+-#define SYSMIX_ENABLEMMX	0x01
+-#define SYSMIX_WINDOWSNT	0x02
+-#define SYSMIX_SLOWCPU		0x04
+-#define SYSMIX_FASTCPU		0x08
+-
+-// Module flags
+-#define SONG_EMBEDMIDICFG	0x0001
+-#define SONG_FASTVOLSLIDES	0x0002
+-#define SONG_ITOLDEFFECTS	0x0004
+-#define SONG_ITCOMPATMODE	0x0008
+-#define SONG_LINEARSLIDES	0x0010
+-#define SONG_PATTERNLOOP	0x0020
+-#define SONG_STEP			0x0040
+-#define SONG_PAUSED			0x0080
+-#define SONG_FADINGSONG		0x0100
+-#define SONG_ENDREACHED		0x0200
+-#define SONG_GLOBALFADE		0x0400
+-#define SONG_CPUVERYHIGH	0x0800
+-#define SONG_FIRSTTICK		0x1000
+-#define SONG_MPTFILTERMODE	0x2000
+-#define SONG_SURROUNDPAN	0x4000
+-#define SONG_EXFILTERRANGE	0x8000
+-#define SONG_AMIGALIMITS	0x10000
+-#define SONG_INSTRUMENTMODE	0x20000
+-#define SONG_ORDERLOCKED	0x40000
+-#define SONG_NOSTEREO		0x80000
+-
+-// Global Options (Renderer)
+-#define SNDMIX_REVERSESTEREO	0x0001
+-#define SNDMIX_NOISEREDUCTION	0x0002
+-#define SNDMIX_AGC				0x0004
+-#define SNDMIX_NORESAMPLING		0x0008
+-#define SNDMIX_HQRESAMPLER		0x0010
+-#define SNDMIX_MEGABASS			0x0020
+-#define SNDMIX_SURROUND			0x0040
+-#define SNDMIX_REVERB			0x0080
+-#define SNDMIX_EQ				0x0100
+-#define SNDMIX_SOFTPANNING		0x0200
+-#define SNDMIX_ULTRAHQSRCMODE	0x0400
+-// Misc Flags (can safely be turned on or off)
+-#define SNDMIX_DIRECTTODISK		0x10000
+-#define SNDMIX_ENABLEMMX		0x20000
+-#define SNDMIX_NOBACKWARDJUMPS	0x40000
+-#define SNDMIX_MAXDEFAULTPAN	0x80000	// Used by the MOD loader
+-#define SNDMIX_MUTECHNMODE                0x100000        // Notes are not played on muted channels
+-#define SNDMIX_NOSURROUND 0x200000
+-#define SNDMIX_NOMIXING	  0x400000	// don't actually do any mixing (values only)
+-#define SNDMIX_NORAMPING  0x800000
+-
+-// Reverb Types (GM2 Presets)
+-enum {
+-	REVERBTYPE_SMALLROOM,
+-	REVERBTYPE_MEDIUMROOM,
+-	REVERBTYPE_LARGEROOM,
+-	REVERBTYPE_SMALLHALL,
+-	REVERBTYPE_MEDIUMHALL,
+-	REVERBTYPE_LARGEHALL,
+-	NUM_REVERBTYPES
+-};
+-
+-
+-enum {
+-	SRCMODE_NEAREST,
+-	SRCMODE_LINEAR,
+-	SRCMODE_SPLINE,
+-	SRCMODE_POLYPHASE,
+-	NUM_SRC_MODES
+-};
+-
+-
+-// Sample Struct
+-typedef struct _MODINSTRUMENT
+-{
+-	UINT nLength,nLoopStart,nLoopEnd;
+-	UINT nSustainStart, nSustainEnd;
+-	signed char *pSample;
+-	UINT nC4Speed;
+-	UINT nPan;
+-	UINT nVolume;
+-	UINT nGlobalVol;
+-	UINT uFlags;
+-	int RelativeTone;
+-	int nFineTune;
+-	UINT nVibType;
+-	UINT nVibSweep;
+-	UINT nVibDepth;
+-	UINT nVibRate;
+-	CHAR name[22];
+-	int played; // for note playback dots
+-} MODINSTRUMENT;
+-
+-typedef struct _INSTRUMENTENVELOPE {
+-	int Ticks[32];
+-	BYTE Values[32];
+-	int nNodes;
+-	int nLoopStart;
+-	int nLoopEnd;
+-	int nSustainStart;
+-	int nSustainEnd;
+-} INSTRUMENTENVELOPE;
+-
+-
+-// Instrument Struct
+-typedef struct _INSTRUMENTHEADER
+-{
+-	UINT nFadeOut;
+-	DWORD dwFlags;
+-	unsigned int nGlobalVol;
+-	unsigned int nPan;
+-	unsigned int Keyboard[128];
+-	unsigned int NoteMap[128];
+-	INSTRUMENTENVELOPE VolEnv;
+-	INSTRUMENTENVELOPE PanEnv;
+-	INSTRUMENTENVELOPE PitchEnv;
+-	unsigned int nNNA;
+-	unsigned int nDCT;
+-	unsigned int nDNA;
+-	unsigned int nPanSwing;
+-	unsigned int nVolSwing;
+-	unsigned int nIFC;
+-	unsigned int nIFR;
+-	unsigned int wMidiBank;
+-	unsigned int nMidiProgram;
+-	unsigned int nMidiChannel;
+-	unsigned int nMidiDrumKey;
+-	int nPPS;
+-	unsigned int nPPC;
+-	CHAR name[32];
+-	CHAR filename[12];
+-	int played; // for note playback dots
+-} INSTRUMENTHEADER;
+-
+-
+-// Channel Struct
+-typedef struct _MODCHANNEL
+-{
+-	// First 32-bytes: Most used mixing information: don't change it
+-	signed char * pCurrentSample;
+-	DWORD nPos;
+-	DWORD nPosLo;	// actually 16-bit
+-	unsigned int topnote_offset;
+-	LONG nInc;		// 16.16
+-	LONG nRightVol;
+-	LONG nLeftVol;
+-	LONG nRightRamp;
+-	LONG nLeftRamp;
+-	// 2nd cache line
+-	DWORD nLength;
+-	DWORD dwFlags;
+-	DWORD nLoopStart;
+-	DWORD nLoopEnd;
+-	LONG nRampRightVol;
+-	LONG nRampLeftVol;
+-
+-	double nFilter_Y1, nFilter_Y2, nFilter_Y3, nFilter_Y4;
+-	double nFilter_A0, nFilter_B0, nFilter_B1;
+-
+-	LONG nROfs, nLOfs;
+-	LONG nRampLength;
+-	// Information not used in the mixer
+-	signed char * pSample;
+-	LONG nNewRightVol, nNewLeftVol;
+-	LONG nRealVolume, nRealPan;
+-	LONG nVolume, nPan, nFadeOutVol;
+-	LONG nPeriod, nC4Speed, sample_freq, nPortamentoDest;
+-	INSTRUMENTHEADER *pHeader;
+-	MODINSTRUMENT *pInstrument;
+-	int nVolEnvPosition, nPanEnvPosition, nPitchEnvPosition;
+-	DWORD nMasterChn, nVUMeter;
+-	LONG nGlobalVol, nInsVol;
+-	LONG nFineTune, nTranspose;
+-	LONG nPortamentoSlide, nAutoVibDepth;
+-	UINT nAutoVibPos, nVibratoPos, nTremoloPos, nPanbrelloPos;
+-	// 16-bit members
+-	int nVolSwing, nPanSwing;
+-
+-	// formally 8-bit members
+-	unsigned int nNote, nNNA;
+-	unsigned int nNewNote, nNewIns, nCommand, nArpeggio;
+-	unsigned int nOldVolumeSlide, nOldFineVolUpDown;
+-	unsigned int nOldPortaUpDown, nOldFinePortaUpDown;
+-	unsigned int nOldPanSlide, nOldChnVolSlide;
+-	unsigned int nVibratoType, nVibratoSpeed, nVibratoDepth;
+-	unsigned int nTremoloType, nTremoloSpeed, nTremoloDepth;
+-	unsigned int nPanbrelloType, nPanbrelloSpeed, nPanbrelloDepth;
+-	unsigned int nOldCmdEx, nOldVolParam, nOldTempo;
+-	unsigned int nOldOffset, nOldHiOffset;
+-	unsigned int nCutOff, nResonance;
+-	unsigned int nRetrigCount, nRetrigParam;
+-	unsigned int nTremorCount, nTremorParam;
+-	unsigned int nPatternLoop, nPatternLoopCount;
+-	unsigned int nRowNote, nRowInstr;
+-	unsigned int nRowVolCmd, nRowVolume;
+-	unsigned int nRowCommand, nRowParam;
+-	unsigned int nLeftVU, nRightVU;
+-	unsigned int nActiveMacro, nLastInstr;
+-	unsigned int nTickStart;
+-	unsigned int nRealtime;
+-	BYTE stupid_gcc_workaround;
+-
+-} MODCHANNEL;
+-
+-
+-typedef struct _MODCHANNELSETTINGS
+-{
+-	UINT nPan;
+-	UINT nVolume;
+-	DWORD dwFlags;
+-	UINT nMixPlugin;
+-        char szName[MAX_CHANNELNAME];        // changed from CHAR
+-} MODCHANNELSETTINGS;
+-
+-
+-typedef struct _MODCOMMAND
+-{
+-	BYTE note;
+-	BYTE instr;
+-	BYTE volcmd;
+-	BYTE command;
+-	BYTE vol;
+-	BYTE param;
+-} MODCOMMAND, *LPMODCOMMAND;
+-
+-////////////////////////////////////////////////////////////////////
+-// Mix Plugins
+-#define MIXPLUG_MIXREADY			0x01	// Set when cleared
+-
+-class IMixPlugin
+-{
+-public:
+-	virtual ~IMixPlugin() = 0;
+-	virtual int AddRef() = 0;
+-	virtual int Release() = 0;
+-	virtual void SaveAllParameters() = 0;
+-	virtual void RestoreAllParameters() = 0;
+-	virtual void Process(float *pOutL, float *pOutR, unsigned int nSamples) = 0;
+-	virtual void Init(unsigned int nFreq, int bReset) = 0;
+-	virtual void MidiSend(DWORD dwMidiCode) = 0;
+-	virtual void MidiCommand(UINT nMidiCh, UINT nMidiProg, UINT note, UINT vol) = 0;
+-};
+-
+-
+-#define MIXPLUG_INPUTF_MASTEREFFECT		0x01	// Apply to master mix
+-#define MIXPLUG_INPUTF_BYPASS			0x02	// Bypass effect
+-#define MIXPLUG_INPUTF_WETMIX			0x04	// Wet Mix (dry added)
+-
+-typedef struct _SNDMIXPLUGINSTATE
+-{
+-	DWORD dwFlags;					// MIXPLUG_XXXX
+-	LONG nVolDecayL, nVolDecayR;	// Buffer click removal
+-	int *pMixBuffer;				// Stereo effect send buffer
+-	float *pOutBufferL;				// Temp storage for int -> float conversion
+-	float *pOutBufferR;
+-} SNDMIXPLUGINSTATE, *PSNDMIXPLUGINSTATE;
+-
+-typedef struct _SNDMIXPLUGININFO
+-{
+-	DWORD dwPluginId1;
+-	DWORD dwPluginId2;
+-	DWORD dwInputRouting;	// MIXPLUG_INPUTF_XXXX
+-	DWORD dwOutputRouting;	// 0=mix 0x80+=fx
+-	DWORD dwReserved[4];	// Reserved for routing info
+-	CHAR szName[32];
+-	CHAR szLibraryName[64];	// original DLL name
+-} SNDMIXPLUGININFO, *PSNDMIXPLUGININFO; // Size should be 128
+-
+-typedef struct _SNDMIXPLUGIN
+-{
+-	IMixPlugin *pMixPlugin;
+-	PSNDMIXPLUGINSTATE pMixState;
+-	ULONG nPluginDataSize;
+-	PVOID pPluginData;
+-	SNDMIXPLUGININFO Info;
+-} SNDMIXPLUGIN, *PSNDMIXPLUGIN;
+-
+-typedef	BOOL (*PMIXPLUGINCREATEPROC)(PSNDMIXPLUGIN);
+-
+-////////////////////////////////////////////////////////////////////
+-
+-enum {
+-	MIDIOUT_START=0,
+-	MIDIOUT_STOP,
+-	MIDIOUT_TICK,
+-	MIDIOUT_NOTEON,
+-	MIDIOUT_NOTEOFF,
+-	MIDIOUT_VOLUME,
+-	MIDIOUT_PAN,
+-	MIDIOUT_BANKSEL,
+-	MIDIOUT_PROGRAM,
+-};
+-
+-
+-typedef struct MODMIDICFG
+-{
+-        char szMidiGlb[9*32];      // changed from CHAR
+-        char szMidiSFXExt[16*32];  // changed from CHAR
+-        char szMidiZXXExt[128*32]; // changed from CHAR
+-} MODMIDICFG, *LPMODMIDICFG;
+-
+-
+-typedef VOID (* LPSNDMIXHOOKPROC)(int *, unsigned int, unsigned int); // buffer, samples, channels
+-
+-
+-
+-//==============
+-class CSoundFile
+-//==============
+-{
+-public:	// Static Members
+-	static UINT m_nXBassDepth, m_nXBassRange;
+-	static UINT m_nReverbDepth, m_nReverbDelay, gnReverbType;
+-	static UINT m_nProLogicDepth, m_nProLogicDelay;
+-	static UINT m_nMaxMixChannels;
+-	static LONG m_nStreamVolume;
+-	static DWORD gdwSysInfo, gdwSoundSetup, gdwMixingFreq, gnBitsPerSample, gnChannels;
+-	static UINT gnAGC, gnVolumeRampSamples, gnCPUUsage;
+-	static UINT gnVULeft, gnVURight;
+-	static LPSNDMIXHOOKPROC gpSndMixHook;
+-	static PMIXPLUGINCREATEPROC gpMixPluginCreateProc;
+-
+-public:	// for Editing
+-	MODCHANNEL Chn[MAX_CHANNELS];					// Channels
+-	UINT ChnMix[MAX_CHANNELS];						// Channels to be mixed
+-	MODINSTRUMENT Ins[MAX_SAMPLES];					// Instruments
+-	INSTRUMENTHEADER *Headers[MAX_INSTRUMENTS];		// Instrument Headers
+-	MODCHANNELSETTINGS ChnSettings[MAX_BASECHANNELS]; // Channels settings
+-	MODCOMMAND *Patterns[MAX_PATTERNS];				// Patterns
+-	WORD PatternSize[MAX_PATTERNS];					// Patterns Lengths
+-	WORD PatternAllocSize[MAX_PATTERNS];				// Allocated pattern lengths (for async. resizing/playback)
+-	BYTE Order[MAX_ORDERS];							// Pattern Orders
+-	MODMIDICFG m_MidiCfg;							// Midi macro config table
+-	SNDMIXPLUGIN m_MixPlugins[MAX_MIXPLUGINS];		// Mix plugins
+-	UINT m_nDefaultSpeed, m_nDefaultTempo, m_nDefaultGlobalVolume;
+-	DWORD m_dwSongFlags;							// Song flags SONG_XXXX
+-	UINT m_nStereoSeparation;
+-	UINT m_nChannels, m_nMixChannels, m_nMixStat, m_nBufferCount;
+-	UINT m_nType, m_nSamples, m_nInstruments;
+-	UINT m_nTickCount, m_nTotalCount, m_nPatternDelay, m_nFrameDelay;
+-	UINT m_nMusicSpeed, m_nMusicTempo;
+-	UINT m_nNextRow, m_nRow;
+-	UINT m_nPattern,m_nCurrentPattern,m_nNextPattern,m_nLockedPattern,m_nRestartPos;
+-	UINT m_nMasterVolume, m_nGlobalVolume, m_nSongPreAmp;
+-	UINT m_nFreqFactor, m_nTempoFactor, m_nOldGlbVolSlide;
+-	LONG m_nMinPeriod, m_nMaxPeriod, m_nRepeatCount, m_nInitialRepeatCount;
+-	DWORD m_nGlobalFadeSamples, m_nGlobalFadeMaxSamples;
+-	BYTE m_rowHighlightMajor, m_rowHighlightMinor;
+-	UINT m_nPatternNames;
+-	LPSTR m_lpszSongComments, m_lpszPatternNames;
+-	char m_szNames[MAX_INSTRUMENTS][32];    // changed from CHAR
+-	CHAR CompressionTable[16];
+-
+-public:
+-	CSoundFile();
+-	~CSoundFile();
+-
+-public:
+-	BOOL Create(LPCBYTE lpStream, DWORD dwMemLength=0);
+-	BOOL Destroy();
+-	UINT GetHighestUsedChannel();
+-	UINT GetType() const { return m_nType; }
+-	UINT GetNumChannels() const;
+-	UINT GetLogicalChannels() const { return m_nChannels; }
+-	BOOL SetMasterVolume(UINT vol, BOOL bAdjustAGC=FALSE);
+-	UINT GetMasterVolume() const { return m_nMasterVolume; }
+-	UINT GetNumPatterns() const;
+-	UINT GetNumInstruments() const;
+-	UINT GetNumSamples() const { return m_nSamples; }
+-	UINT GetCurrentPos() const;
+-	UINT GetCurrentPattern() const { return m_nPattern; }
+-	UINT GetCurrentOrder() const { return m_nCurrentPattern; }
+-	UINT GetSongComments(LPSTR s, UINT cbsize, UINT linesize=32);
+-	UINT GetRawSongComments(LPSTR s, UINT cbsize, UINT linesize=32);
+-	UINT GetMaxPosition() const;
+-	void SetCurrentPos(UINT nPos);
+-	void SetCurrentOrder(UINT nOrder);
+-	void GetTitle(LPSTR s) const { lstrcpyn(s,m_szNames[0],32); }
+-	LPCSTR GetTitle() const { return m_szNames[0]; }
+-	UINT GetSampleName(UINT nSample,LPSTR s=NULL) const;
+-	UINT GetInstrumentName(UINT nInstr,LPSTR s=NULL) const;
+-	UINT GetMusicSpeed() const { return m_nMusicSpeed; }
+-	UINT GetMusicTempo() const { return m_nMusicTempo; }
+-	DWORD GetLength(BOOL bAdjust, BOOL bTotal=FALSE);
+-	DWORD GetSongTime() { return GetLength(FALSE, TRUE); }
+-	void SetRepeatCount(int n) { m_nRepeatCount = n; m_nInitialRepeatCount = n; }
+-	int GetRepeatCount() const { return m_nRepeatCount; }
+-	BOOL IsPaused() const {	return (m_dwSongFlags & SONG_PAUSED) ? TRUE : FALSE; }
+-	void LoopPattern(int nPat, int nRow=0);
+-	void CheckCPUUsage(UINT nCPU);
+-	BOOL SetPatternName(UINT nPat, LPCSTR lpszName);
+-	BOOL GetPatternName(UINT nPat, LPSTR lpszName, UINT cbSize=MAX_PATTERNNAME) const;
+-	// Module Loaders
+-	BOOL ReadXM(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadS3M(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadMod(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadMed(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadMTM(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadSTM(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadIT(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL Read669(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadUlt(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadWav(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadDSM(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadFAR(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadAMS(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadMDL(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadOKT(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadDMF(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadPTM(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadDBM(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadAMF(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadMT2(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadPSM(LPCBYTE lpStream, DWORD dwMemLength);
+-	BOOL ReadUMX(LPCBYTE lpStream, DWORD dwMemLength);
+-	// MOD Convert function
+-	UINT GetBestSaveFormat() const;
+-	UINT GetSaveFormats() const;
+-	void ConvertModCommand(MODCOMMAND *) const;
+-	void S3MConvert(MODCOMMAND *m, BOOL bIT) const;
+-	void S3MSaveConvert(UINT *pcmd, UINT *pprm, BOOL bIT) const;
+-	WORD ModSaveCommand(const MODCOMMAND *m, BOOL bXM) const;
+-public:
+-	// backhooks :)
+-	static void (*_midi_out_note)(int chan, const MODCOMMAND *m);
+-	static void (*_midi_out_raw)(unsigned char *,unsigned int, unsigned int);
+-
+-public:
+-	// Real-time sound functions
+-	VOID ResetChannels();
+-
+-	UINT Read(LPVOID lpBuffer, UINT cbBuffer);
+-	UINT CreateStereoMix(int count);
+-	BOOL FadeSong(UINT msec);
+-	BOOL GlobalFadeSong(UINT msec);
+-	UINT GetTotalTickCount() const { return m_nTotalCount; }
+-	VOID ResetTotalTickCount() { m_nTotalCount = 0; }
+-
+-public:
+-	// Mixer Config
+-	static BOOL InitPlayer(BOOL bReset=FALSE);
+-	static BOOL SetWaveConfig(UINT nRate,UINT nBits,UINT nChannels,BOOL bMMX=FALSE);
+-	static BOOL SetResamplingMode(UINT nMode); // SRCMODE_XXXX
+-	static BOOL IsStereo() { return (gnChannels > 1) ? TRUE : FALSE; }
+-	static DWORD GetSampleRate() { return gdwMixingFreq; }
+-	static DWORD GetBitsPerSample() { return gnBitsPerSample; }
+-	static DWORD InitSysInfo();
+-	static DWORD GetSysInfo() { return gdwSysInfo; }
+-	// AGC
+-	static BOOL GetAGC() { return (gdwSoundSetup & SNDMIX_AGC) ? TRUE : FALSE; }
+-	static void SetAGC(BOOL b);
+-	static void ResetAGC();
+-	static void ProcessAGC(int count);
+-
+-	// Floats
+-	static VOID StereoMixToFloat(const int *pSrc, float *pOut1, float *pOut2, UINT nCount);
+-	static VOID FloatToStereoMix(const float *pIn1, const float *pIn2, int *pOut, UINT nCount);
+-	static VOID MonoMixToFloat(const int *pSrc, float *pOut, UINT nCount);
+-	static VOID FloatToMonoMix(const float *pIn, int *pOut, UINT nCount);
+-	
+-	
+-	
+-	
+-
+-	// wee...
+-        static void InitializeEQ(BOOL bReset=TRUE);
+-        static void SetEQGains(const UINT *pGains, UINT nBands, const UINT *pFreqs=NULL, BOOL bReset=FALSE);    // 0=-12dB, 32=+12dB
+-        /*static*/ void EQStereo(int *pbuffer, UINT nCount);
+-        /*static*/ void EQMono(int *pbuffer, UINT nCount);
+-
+-
+-	//GCCFIX -- added these functions back in!
+-	static BOOL SetWaveConfigEx(BOOL bSurround,BOOL bNoOverSampling,BOOL bReverb,BOOL hqido,BOOL bMegaBass,BOOL bNR,BOOL bEQ);
+-	// DSP Effects
+-	static void InitializeDSP(BOOL bReset);
+-	static void ProcessStereoDSP(int count);
+-	static void ProcessMonoDSP(int count);
+-	// [Reverb level 0(quiet)-100(loud)], [delay in ms, usually 40-200ms]
+-	static BOOL SetReverbParameters(UINT nDepth, UINT nDelay);
+-	// [XBass level 0(quiet)-100(loud)], [cutoff in Hz 10-100]
+-	static BOOL SetXBassParameters(UINT nDepth, UINT nRange);
+-	// [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-40ms]
+-	static BOOL SetSurroundParameters(UINT nDepth, UINT nDelay);
+-public:
+-	BOOL ReadNote();
+-	BOOL ProcessRow();
+-	BOOL ProcessEffects();
+-	UINT GetNNAChannel(UINT nChn);
+-	void CheckNNA(UINT nChn, UINT instr, int note, BOOL bForceCut);
+-	void NoteChange(UINT nChn, int note, BOOL bPorta=FALSE, BOOL bResetEnv=TRUE, BOOL bManual=FALSE);
+-	void InstrumentChange(MODCHANNEL *pChn, UINT instr, BOOL bPorta=FALSE,BOOL bUpdVol=TRUE,BOOL bResetEnv=TRUE);
+-	// Channel Effects
+-	void PortamentoUp(MODCHANNEL *pChn, UINT param);
+-	void PortamentoDown(MODCHANNEL *pChn, UINT param);
+-	void FinePortamentoUp(MODCHANNEL *pChn, UINT param);
+-	void FinePortamentoDown(MODCHANNEL *pChn, UINT param);
+-	void ExtraFinePortamentoUp(MODCHANNEL *pChn, UINT param);
+-	void ExtraFinePortamentoDown(MODCHANNEL *pChn, UINT param);
+-	void TonePortamento(MODCHANNEL *pChn, UINT param);
+-	void Vibrato(MODCHANNEL *pChn, UINT param);
+-	void FineVibrato(MODCHANNEL *pChn, UINT param);
+-	void VolumeSlide(MODCHANNEL *pChn, UINT param);
+-	void PanningSlide(MODCHANNEL *pChn, UINT param);
+-	void ChannelVolSlide(MODCHANNEL *pChn, UINT param);
+-	void FineVolumeUp(MODCHANNEL *pChn, UINT param);
+-	void FineVolumeDown(MODCHANNEL *pChn, UINT param);
+-	void Tremolo(MODCHANNEL *pChn, UINT param);
+-	void Panbrello(MODCHANNEL *pChn, UINT param);
+-	void RetrigNote(UINT nChn, UINT param);
+-	void NoteCut(UINT nChn, UINT nTick);
+-	void KeyOff(UINT nChn);
+-	int PatternLoop(MODCHANNEL *, UINT param);
+-	void ExtendedMODCommands(UINT nChn, UINT param);
+-	void ExtendedS3MCommands(UINT nChn, UINT param);
+-	void ExtendedChannelEffect(MODCHANNEL *, UINT param);
+-	void MidiSend(unsigned char *data, unsigned int len, UINT nChn=0, int fake = 0);
+-	void ProcessMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param=0,
+-			UINT note=0, UINT velocity=0, UINT use_instr=0);
+-	void SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier=256,int freq=0) const;
+-	// Low-Level effect processing
+-	void DoFreqSlide(MODCHANNEL *pChn, LONG nFreqSlide);
+-	// Global Effects
+-	void SetTempo(UINT param);
+-	void SetSpeed(UINT param);
+-	void GlobalVolSlide(UINT param);
+-	DWORD IsSongFinished(UINT nOrder, UINT nRow) const;
+-	BOOL IsValidBackwardJump(UINT nStartOrder, UINT nStartRow, UINT nJumpOrder, UINT nJumpRow) const;
+-	// Read/Write sample functions
+-	signed char GetDeltaValue(signed char prev, UINT n) const { return (signed char)(prev + CompressionTable[n & 0x0F]); }
+-	UINT PackSample(int &sample, int next);
+-	BOOL CanPackSample(LPSTR pSample, UINT nLen, UINT nPacking, BYTE *result=NULL);
+-	UINT ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR pMemFile, DWORD dwMemLength);
+-	BOOL DestroySample(UINT nSample);
+-	BOOL DestroyInstrument(UINT nInstr);
+-	BOOL IsSampleUsed(UINT nSample);
+-	BOOL IsInstrumentUsed(UINT nInstr);
+-	BOOL RemoveInstrumentSamples(UINT nInstr);
+-	UINT DetectUnusedSamples(BOOL *);
+-	BOOL RemoveSelectedSamples(BOOL *);
+-	void AdjustSampleLoop(MODINSTRUMENT *pIns);
+-	// I/O from another sound file
+-	BOOL ReadInstrumentFromSong(UINT nInstr, CSoundFile *, UINT nSrcInstrument);
+-	BOOL ReadSampleFromSong(UINT nSample, CSoundFile *, UINT nSrcSample);
+-	// Period/Note functions
+-	UINT GetNoteFromPeriod(UINT period) const;
+-	UINT GetPeriodFromNote(UINT note, int nFineTune, UINT nC4Speed) const;
+-	UINT GetLinearPeriodFromNote(UINT note, int nFineTune, UINT nC4Speed) const;
+-	UINT GetFreqFromPeriod(UINT period, UINT nC4Speed, int nPeriodFrac=0) const;
+-	// Misc functions
+-	MODINSTRUMENT *GetSample(UINT n) { return Ins+n; }
+-	void ResetMidiCfg();
+-	UINT MapMidiInstrument(DWORD dwProgram, UINT nChannel, UINT nNote);
+-	BOOL ITInstrToMPT(const void *p, INSTRUMENTHEADER *penv, UINT trkvers);
+-	UINT SaveMixPlugins(FILE *f=NULL, BOOL bUpdate=TRUE);
+-	UINT LoadMixPlugins(const void *pData, UINT nLen);
+-	void ResetTimestamps(); // for note playback dots
+-
+-	// Static helper functions
+-public:
+-	static DWORD TransposeToFrequency(int transp, int ftune=0);
+-	static int FrequencyToTranspose(DWORD freq);
+-	static void FrequencyToTranspose(MODINSTRUMENT *psmp);
+-
+-	// System-Dependant functions
+-public:
+-	static MODCOMMAND *AllocatePattern(UINT rows, UINT nchns);
+-	static signed char* AllocateSample(UINT nbytes);
+-	static void FreePattern(LPVOID pat);
+-	static void FreeSample(LPVOID p);
+-	static UINT Normalize24BitBuffer(LPBYTE pbuffer, UINT cbsizebytes, DWORD lmax24, DWORD dwByteInc);
+-};
+-
+-
+-// inline DWORD BigEndian(DWORD x) { return ((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | ((x & 0xFF000000) >> 24); }
+-// inline WORD BigEndianW(WORD x) { return (WORD)(((x >> 8) & 0xFF) | ((x << 8) & 0xFF00)); }
+-
+-
+-//////////////////////////////////////////////////////////
+-// WAVE format information
+-
+-#pragma pack(1)
+-
+-// Standard IFF chunks IDs
+-#define IFFID_FORM		0x4d524f46
+-#define IFFID_RIFF		0x46464952
+-#define IFFID_WAVE		0x45564157
+-#define IFFID_LIST		0x5453494C
+-#define IFFID_INFO		0x4F464E49
+-
+-// IFF Info fields
+-#define IFFID_ICOP		0x504F4349
+-#define IFFID_IART		0x54524149
+-#define IFFID_IPRD		0x44525049
+-#define IFFID_INAM		0x4D414E49
+-#define IFFID_ICMT		0x544D4349
+-#define IFFID_IENG		0x474E4549
+-#define IFFID_ISFT		0x54465349
+-#define IFFID_ISBJ		0x4A425349
+-#define IFFID_IGNR		0x524E4749
+-#define IFFID_ICRD		0x44524349
+-
+-// Wave IFF chunks IDs
+-#define IFFID_wave		0x65766177
+-#define IFFID_fmt		0x20746D66
+-#define IFFID_wsmp		0x706D7377
+-#define IFFID_pcm		0x206d6370
+-#define IFFID_data		0x61746164
+-#define IFFID_smpl		0x6C706D73
+-#define IFFID_xtra		0x61727478
+-
+-typedef struct WAVEFILEHEADER
+-{
+-	DWORD id_RIFF;		// "RIFF"
+-	DWORD filesize;		// file length-8
+-	DWORD id_WAVE;
+-} WAVEFILEHEADER;
+-
+-
+-typedef struct WAVEFORMATHEADER
+-{
+-	DWORD id_fmt;		// "fmt "
+-	DWORD hdrlen;		// 16
+-	WORD format;		// 1
+-	WORD channels;		// 1:mono, 2:stereo
+-	DWORD freqHz;		// sampling freq
+-	DWORD bytessec;		// bytes/sec=freqHz*samplesize
+-	WORD samplesize;	// sizeof(sample)
+-	WORD bitspersample;	// bits per sample (8/16)
+-} WAVEFORMATHEADER;
+-
+-
+-typedef struct WAVEDATAHEADER
+-{
+-	DWORD id_data;		// "data"
+-	DWORD length;		// length of data
+-} WAVEDATAHEADER;
+-
+-
+-typedef struct WAVESMPLHEADER
+-{
+-	// SMPL
+-	DWORD smpl_id;		// "smpl"	-> 0x6C706D73
+-	DWORD smpl_len;		// length of smpl: 3Ch	(54h with sustain loop)
+-	DWORD dwManufacturer;
+-	DWORD dwProduct;
+-	DWORD dwSamplePeriod;	// 1000000000/freqHz
+-	DWORD dwBaseNote;	// 3Ch = C-4 -> 60 + RelativeTone
+-	DWORD dwPitchFraction;
+-	DWORD dwSMPTEFormat;
+-	DWORD dwSMPTEOffset;
+-	DWORD dwSampleLoops;	// number of loops
+-	DWORD cbSamplerData;
+-} WAVESMPLHEADER;
+-
+-
+-typedef struct SAMPLELOOPSTRUCT
+-{
+-	DWORD dwIdentifier;
+-	DWORD dwLoopType;		// 0=normal, 1=bidi
+-	DWORD dwLoopStart;
+-	DWORD dwLoopEnd;		// Byte offset ?
+-	DWORD dwFraction;
+-	DWORD dwPlayCount;		// Loop Count, 0=infinite
+-} SAMPLELOOPSTRUCT;
+-
+-
+-typedef struct WAVESAMPLERINFO
+-{
+-	WAVESMPLHEADER wsiHdr;
+-	SAMPLELOOPSTRUCT wsiLoops[2];
+-} WAVESAMPLERINFO;
+-
+-
+-typedef struct WAVELISTHEADER
+-{
+-	DWORD list_id;	// "LIST" -> 0x5453494C
+-	DWORD list_len;
+-	DWORD info;		// "INFO"
+-} WAVELISTHEADER;
+-
+-
+-typedef struct WAVEEXTRAHEADER
+-{
+-	DWORD xtra_id;	// "xtra"	-> 0x61727478
+-	DWORD xtra_len;
+-	DWORD dwFlags;
+-	WORD  wPan;
+-	WORD  wVolume;
+-	WORD  wGlobalVol;
+-	WORD  wReserved;
+-	BYTE nVibType;
+-	BYTE nVibSweep;
+-	BYTE nVibDepth;
+-	BYTE nVibRate;
+-} WAVEEXTRAHEADER;
+-
+-#pragma pack()
+-
+-///////////////////////////////////////////////////////////
+-// Low-level Mixing functions
+-
+-#define MIXBUFFERSIZE		512
+-#define MIXING_ATTENUATION	4
+-#define MIXING_CLIPMIN		(-0x04000000)
+-#define MIXING_CLIPMAX		(0x03FFFFFF)
+-#define VOLUMERAMPPRECISION	12
+-#define FADESONGDELAY		100
+-#define EQ_BUFFERSIZE		(MIXBUFFERSIZE)
+-#define AGC_PRECISION		9
+-#define AGC_UNITY			(1 << AGC_PRECISION)
+-
+-// Calling conventions
+-#ifdef MSC_VER
+-#define MPPASMCALL	__cdecl
+-#define MPPFASTCALL	__fastcall
+-#else
+-#define MPPASMCALL
+-#define MPPFASTCALL
+-#endif
+-
+-#define MOD2XMFineTune(k)	((int)( (signed char)((k)<<4) ))
+-#define XM2MODFineTune(k)	((int)( (k>>4)&0x0f ))
+-
+-// Return (a*b)/c - no divide error
+-static inline int _muldiv(int a, int b, int c)
+-{
+-	return ((unsigned long long) a * (unsigned long long) b ) / c;
+-}
+-
+-
+-// Return (a*b+c/2)/c - no divide error
+-static inline int _muldivr(int a, int b, int c)
+-{
+-	return ((unsigned long long) a * (unsigned long long) b + (c >> 1)) / c;
+-}
+-
+-
+-// Byte swapping functions from the GNU C Library and libsdl
+-
+-/* Swap bytes in 16 bit value.  */
+-#ifdef __GNUC__
+-# define bswap_16(x) \
+-    (__extension__							      \
+-     ({ unsigned short int __bsx = (x);					      \
+-        ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8)); }))
+-#else
+-static __inline unsigned short int
+-bswap_16 (unsigned short int __bsx)
+-{
+-  return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8));
+-}
+-#endif
+-
+-/* Swap bytes in 32 bit value.  */
+-#ifdef __GNUC__
+-# define bswap_32(x) \
+-    (__extension__							      \
+-     ({ unsigned int __bsx = (x);					      \
+-        ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >>  8) |    \
+-	 (((__bsx) & 0x0000ff00) <<  8) | (((__bsx) & 0x000000ff) << 24)); }))
+-#else
+-static __inline unsigned int
+-bswap_32 (unsigned int __bsx)
+-{
+-  return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >>  8) |
+-	  (((__bsx) & 0x0000ff00) <<  8) | (((__bsx) & 0x000000ff) << 24));
+-}
+-#endif
+-
+-#if (defined ARM) && (defined _WIN32_WCE)
+-static __inline unsigned short int
+-ARM_get16(const void *data)
+-{
+-	unsigned short int s;
+-	memcpy(&s,data,sizeof(s));
+-	return s;
+-}
+-
+-static __inline unsigned int
+-ARM_get32(const void *data)
+-{
+-	unsigned int s;
+-	memcpy(&s,data,sizeof(s));
+-	return s;
+-}
+-
+-#define bswapLE16(X) ARM_get16(&X)
+-#define bswapLE32(X) ARM_get32(&X)
+-#define bswapBE16(X) bswap_16(ARM_get16(&X))
+-#define bswapBE32(X) bswap_32(ARM_get32(&X))
+-
+-// From libsdl
+-#elif WORDS_BIGENDIAN
+-#define bswapLE16(X) bswap_16(X)
+-#define bswapLE32(X) bswap_32(X)
+-#define bswapBE16(X) (X)
+-#define bswapBE32(X) (X)
+-#else
+-#define bswapLE16(X) (X)
+-#define bswapLE32(X) (X)
+-#define bswapBE16(X) bswap_16(X)
+-#define bswapBE32(X) bswap_32(X)
+-#endif
+-
+-#endif
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/snd_flt.cxx audacious-plugins-2.5.4/src/modplug/snd_flt.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/snd_flt.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/snd_flt.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,130 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-// AWE32: cutoff = reg[0-255] * 31.25 + 100 -> [100Hz-8060Hz]
+-// EMU10K1 docs: cutoff = reg[0-127]*62+100
+-
+-#ifndef NO_FILTER
+-
+-static int filter_cutoff[] = {
+-     130,  132,  134,  136,  138,  140,  142,  144,
+-     146,  148,  151,  153,  155,  157,  160,  162,
+-     164,  167,  169,  172,  174,  177,  179,  182,
+-     184,  187,  190,  193,  195,  198,  201,  204,
+-     207,  210,  213,  216,  220,  223,  226,  229,
+-     233,  236,  239,  243,  246,  250,  254,  257,
+-     261,  265,  269,  273,  277,  281,  285,  289,
+-     293,  297,  302,  306,  311,  315,  320,  324,
+-     329,  334,  339,  344,  349,  354,  359,  364,
+-     369,  375,  380,  386,  391,  397,  403,  409,
+-     415,  421,  427,  433,  440,  446,  452,  459,
+-     466,  472,  479,  486,  493,  501,  508,  515,
+-     523,  530,  538,  546,  554,  562,  570,  578,
+-     587,  595,  604,  613,  622,  631,  640,  649,
+-     659,  668,  678,  688,  698,  708,  718,  729,
+-     739,  750,  761,  772,  783,  795,  806,  818,
+-     830,  842,  854,  867,  880,  892,  905,  918,
+-     932,  945,  959,  973,  987, 1002, 1016, 1031,
+-    1046, 1061, 1077, 1092, 1108, 1124, 1141, 1157,
+-    1174, 1191, 1209, 1226, 1244, 1262, 1280, 1299,
+-    1318, 1337, 1357, 1376, 1396, 1417, 1437, 1458,
+-    1479, 1501, 1523, 1545, 1567, 1590, 1613, 1637,
+-    1661, 1685, 1709, 1734, 1760, 1785, 1811, 1837,
+-    1864, 1891, 1919, 1947, 1975, 2004, 2033, 2062,
+-    2093, 2123, 2154, 2185, 2217, 2249, 2282, 2315,
+-    2349, 2383, 2418, 2453, 2489, 2525, 2561, 2599,
+-    2637, 2675, 2714, 2753, 2793, 2834, 2875, 2917,
+-    2959, 3003, 3046, 3091, 3135, 3181, 3227, 3274,
+-    3322, 3370, 3419, 3469, 3520, 3571, 3623, 3675,
+-    3729, 3783, 3838, 3894, 3951, 4008, 4066, 4125,
+-    4186, 4246, 4308, 4371, 4434, 4499, 4564, 4631,
+-    4698, 4766, 4836, 4906, 4978, 5050, 5123, 5198
+-};
+-int dmpfac[] = {
+-    131072, 128272, 125533, 122852, 120229, 117661, 115148, 112689,
+-    110283, 107928, 105623, 103367, 101160,  98999,  96885,  94816,
+-     92791,  90810,  88870,  86973,  85115,  83298,  81519,  79778,
+-     78074,  76407,  74775,  73178,  71615,  70086,  68589,  67125,
+-     65691,  64288,  62915,  61572,  60257,  58970,  57711,  56478,
+-     55272,  54092,  52937,  51806,  50700,  49617,  48557,  47520,
+-     46506,  45512,  44540,  43589,  42658,  41747,  40856,  39983,
+-     39130,  38294,  37476,  36676,  35893,  35126,  34376,  33642,
+-     32923,  32220,  31532,  30859,  30200,  29555,  28924,  28306,
+-     27701,  27110,  26531,  25964,  25410,  24867,  24336,  23816,
+-     23308,  22810,  22323,  21846,  21380,  20923,  20476,  20039,
+-     19611,  19192,  18782,  18381,  17989,  17604,  17228,  16861,
+-     16500,  16148,  15803,  15466,  15135,  14812,  14496,  14186,
+-     13883,  13587,  13297,  13013,  12735,  12463,  12197,  11936,
+-     11681,  11432,  11188,  10949,  10715,  10486,  10262,  10043,
+-      9829,   9619,   9413,   9212,   9015,   8823,   8634,   8450,
+-      8270,   8093,   7920,   7751,   7585,   7423,   7265,   7110,
+-      6958,   6809,   6664,   6522,   6382,   6246,   6113,   5982,
+-      5854,   5729,   5607,   5487,   5370,   5255,   5143,   5033,
+-      4926,   4820,   4718,   4617,   4518,   4422,   4327,   4235,
+-      4144,   4056,   3969,   3884,   3801,   3720,   3641,   3563,
+-      3487,   3412,   3340,   3268,   3198,   3130,   3063,   2998,
+-      2934,   2871,   2810,   2750,   2691,   2634,   2577,   2522,
+-      2468,   2416,   2364,   2314,   2264,   2216,   2169,   2122,
+-      2077,   2032,   1989,   1947,   1905,   1864,   1824,   1786,
+-      1747,   1710,   1674,   1638,   1603,   1569,   1535,   1502,
+-      1470,   1439,   1408,   1378,   1348,   1320,   1291,   1264,
+-      1237,   1210,   1185,   1159,   1135,   1110,   1087,   1063,
+-      1041,   1018,    997,    975,    955,    934,    914,    895,
+-       876,    857,    838,    821,    803,    786,    769,    753,
+-       737,    721,    705,    690,    676,    661,    647,    633,
+-       620,    606,    593,    581,    568,    556,    544,    533
+-};
+-
+-
+-#include <math.h>
+-
+-
+-#define PI	((double)3.14159265358979323846)
+-// Simple 2-poles resonant filter
+-void CSoundFile::SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier, int) const
+-//----------------------------------------------------------------------------------------
+-{
+-	int cutoff = pChn->nCutOff * 2;
+-	cutoff *= (flt_modifier+256) / 2;
+-	cutoff /= 256;
+-	if (cutoff>=255) cutoff=255;
+-
+-	int resonance = pChn->nResonance;
+-	if (resonance>=255) resonance=255;
+-
+-        float fc = (float)filter_cutoff[cutoff];
+-        float fs = (float)gdwMixingFreq;
+-        float fg, fb0, fb1;
+-        float d2, d, e;
+-
+-        fc *= 3.14159265358979 * 2 / fs;
+-        d2 = ((float)dmpfac[resonance]) / 65536.0;
+-        d = (1.0 - d2) * fc;
+-
+-        if (d > 2.0)
+-                d = 2.0;
+-
+-        d = (d2 - d) / fc;
+-        e = 1.0 / (fc * fc);
+-
+-        fg = 1.0 / (1 + d + e);
+-        fb0 = (d + e + e) / (1 + d + e);
+-        fb1 = -e / (1 + d + e);
+-
+-	pChn->nFilter_A0 = (double)fg;
+-	pChn->nFilter_B0 = (double)fb0;
+-	pChn->nFilter_B1 = (double)fb1;
+-	
+-	if (bReset) {
+-		pChn->nFilter_Y1 = pChn->nFilter_Y2 = 0;
+-		pChn->nFilter_Y3 = pChn->nFilter_Y4 = 0;
+-	}
+-	pChn->dwFlags |= CHN_FILTER;
+-}
+-#endif // NO_FILTER
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/snd_fx.cxx audacious-plugins-2.5.4/src/modplug/snd_fx.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/snd_fx.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/snd_fx.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,2614 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-#ifdef MSC_VER
+-#pragma warning(disable:4244)
+-#endif
+-
+-// Tables defined in tables.cpp
+-extern BYTE ImpulseTrackerPortaVolCmd[16];
+-extern WORD S3MFineTuneTable[16];
+-extern WORD ProTrackerPeriodTable[6*12];
+-extern WORD ProTrackerTunedPeriods[15*12];
+-extern WORD FreqS3MTable[];
+-extern WORD XMPeriodTable[96+8];
+-extern UINT XMLinearTable[768];
+-extern DWORD FineLinearSlideUpTable[16];
+-extern DWORD FineLinearSlideDownTable[16];
+-extern DWORD LinearSlideUpTable[256];
+-extern DWORD LinearSlideDownTable[256];
+-extern signed char retrigTable1[16];
+-extern signed char retrigTable2[16];
+-extern short int ModRandomTable[64];
+-
+-
+-////////////////////////////////////////////////////////////
+-// Length
+-
+-DWORD CSoundFile::GetLength(BOOL bAdjust, BOOL bTotal)
+-//----------------------------------------------------
+-{
+-	UINT dwElapsedTime=0, nRow=0, nCurrentPattern=0, nNextPattern=0, nPattern=Order[0];
+-	UINT nMusicSpeed=m_nDefaultSpeed, nMusicTempo=m_nDefaultTempo, nNextRow=0;
+-	UINT nMaxRow = 0, nMaxPattern = 0;
+-	LONG nGlbVol = m_nDefaultGlobalVolume, nOldGlbVolSlide = 0;
+-	BYTE samples[MAX_CHANNELS];
+-	BYTE instr[MAX_CHANNELS];
+-	BYTE notes[MAX_CHANNELS];
+-	BYTE vols[MAX_CHANNELS];
+-	BYTE oldparam[MAX_CHANNELS];
+-	BYTE chnvols[MAX_CHANNELS];
+-	DWORD patloop[MAX_CHANNELS];
+-
+-	memset(instr, 0, sizeof(instr));
+-	memset(notes, 0, sizeof(notes));
+-	memset(vols, 0xFF, sizeof(vols));
+-	memset(patloop, 0, sizeof(patloop));
+-	memset(oldparam, 0, sizeof(oldparam));
+-	memset(chnvols, 64, sizeof(chnvols));
+-	memset(samples, 0, sizeof(samples));
+-	for (UINT icv=0; icv<m_nChannels; icv++) chnvols[icv] = ChnSettings[icv].nVolume;
+-	nMaxRow = m_nNextRow;
+-	nMaxPattern = m_nNextPattern;
+-	nCurrentPattern = nNextPattern = 0;
+-	nPattern = Order[0];
+-	nRow = nNextRow = 0;
+-	for (;;)
+-	{
+-		UINT nSpeedCount = 0;
+-		nRow = nNextRow;
+-		nCurrentPattern = nNextPattern;
+-
+-		// Check if pattern is valid
+-		nPattern = Order[nCurrentPattern];
+-		while (nPattern >= MAX_PATTERNS)
+-		{
+-			// End of song ?
+-			if ((nPattern == 0xFF) || (nCurrentPattern >= MAX_ORDERS))
+-			{
+-				goto EndMod;
+-			} else
+-			{
+-				nCurrentPattern++;
+-				nPattern = (nCurrentPattern < MAX_ORDERS) ? Order[nCurrentPattern] : 0xFF;
+-			}
+-			nNextPattern = nCurrentPattern;
+-		}
+-		// Weird stuff?
+-		if ((nPattern >= MAX_PATTERNS) || (!Patterns[nPattern])) break;
+-		// Should never happen
+-		if (nRow >= PatternSize[nPattern]) nRow = 0;
+-		// Update next position
+-		nNextRow = nRow + 1;
+-		if (nNextRow >= PatternSize[nPattern])
+-		{
+-			nNextPattern = nCurrentPattern + 1;
+-			nNextRow = 0;
+-		}
+-		if (!nRow)
+-		{
+-			for (UINT ipck=0; ipck<m_nChannels; ipck++) patloop[ipck] = dwElapsedTime;
+-		}
+-		if (!bTotal)
+-		{
+-			if ((nCurrentPattern > nMaxPattern) || ((nCurrentPattern == nMaxPattern) && (nRow >= nMaxRow)))
+-			{
+-				if (bAdjust)
+-				{
+-					m_nMusicSpeed = nMusicSpeed;
+-					m_nMusicTempo = nMusicTempo;
+-				}
+-				break;
+-			}
+-		}
+-		MODCHANNEL *pChn = Chn;
+-		MODCOMMAND *p = Patterns[nPattern] + nRow * m_nChannels;
+-		for (UINT nChn=0; nChn<m_nChannels; p++,pChn++, nChn++) if (*((DWORD *)p))
+-		{
+-			UINT command = p->command;
+-			UINT param = p->param;
+-			UINT note = p->note;
+-			if (p->instr) { instr[nChn] = p->instr; notes[nChn] = 0; vols[nChn] = 0xFF; }
+-			if ((note) && (note <= 120)) notes[nChn] = note;
+-			if (p->volcmd == VOLCMD_VOLUME)	{ vols[nChn] = p->vol; }
+-			if (command) switch (command)
+-			{
+-			// Position Jump
+-			case CMD_POSITIONJUMP:
+-				if (param <= nCurrentPattern) goto EndMod;
+-				nNextPattern = param;
+-				nNextRow = 0;
+-				if (bAdjust)
+-				{
+-					pChn->nPatternLoopCount = 0;
+-					pChn->nPatternLoop = 0;
+-				}
+-				break;
+-			// Pattern Break
+-			case CMD_PATTERNBREAK:
+-				nNextRow = param;
+-				nNextPattern = nCurrentPattern + 1;
+-				if (bAdjust)
+-				{
+-					pChn->nPatternLoopCount = 0;
+-					pChn->nPatternLoop = 0;
+-				}
+-				break;
+-			// Set Speed
+-			case CMD_SPEED:
+-				if (!param) break;
+-				if ((param <= 0x20) || (m_nType != MOD_TYPE_MOD))
+-				{
+-					if (param < 128) nMusicSpeed = param;
+-				}
+-				break;
+-			// Set Tempo
+-			case CMD_TEMPO:
+-				if ((bAdjust) && (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT)))
+-				{
+-					if (param) pChn->nOldTempo = param; else param = pChn->nOldTempo;
+-				}
+-				if (param >= 0x20) nMusicTempo = param; else
+-				// Tempo Slide
+-				// FIXME: this is totally wrong!
+-				if ((param & 0xF0) == 0x10)
+-				{
+-					nMusicTempo += param & 0x0F;
+-					if (nMusicTempo > 255) nMusicTempo = 255;
+-				} else
+-				{
+-					nMusicTempo -= param & 0x0F;
+-					if (nMusicTempo < 32) nMusicTempo = 32;
+-				}
+-				break;
+-			// Pattern Delay
+-			case CMD_S3MCMDEX:
+-				if ((param & 0xF0) == 0x60) { nSpeedCount = param & 0x0F; break; } else
+-				if ((param & 0xF0) == 0xB0) { param &= 0x0F; param |= 0x60; }
+-			case CMD_MODCMDEX:
+-				if ((param & 0xF0) == 0xE0) nSpeedCount = (param & 0x0F) * nMusicSpeed; else
+-				if ((param & 0xF0) == 0x60)
+-				{
+-					if (param & 0x0F) dwElapsedTime += (dwElapsedTime - patloop[nChn]) * (param & 0x0F);
+-					else patloop[nChn] = dwElapsedTime;
+-				}
+-				break;
+-			}
+-			if (!bAdjust) continue;
+-			switch(command)
+-			{
+-			// Portamento Up/Down
+-			case CMD_PORTAMENTOUP:
+-			case CMD_PORTAMENTODOWN:
+-				if (param) pChn->nOldPortaUpDown = param;
+-				break;
+-			// Tone-Portamento
+-			case CMD_TONEPORTAMENTO:
+-				if (param) pChn->nPortamentoSlide = param << 2;
+-				break;
+-			// Offset
+-			case CMD_OFFSET:
+-				if (param) pChn->nOldOffset = param;
+-				break;
+-			// Volume Slide
+-			case CMD_VOLUMESLIDE:
+-			case CMD_TONEPORTAVOL:
+-			case CMD_VIBRATOVOL:
+-				if (param) pChn->nOldVolumeSlide = param;
+-				break;
+-			// Set Volume
+-			case CMD_VOLUME:
+-				vols[nChn] = param;
+-				break;
+-			// Global Volume
+-			case CMD_GLOBALVOLUME:
+-				if (m_nType != MOD_TYPE_IT) param <<= 1;
+-				if (param > 128) param = 128;
+-				nGlbVol = param << 1;
+-				break;
+-			// Global Volume Slide
+-			case CMD_GLOBALVOLSLIDE:
+-				if (param) nOldGlbVolSlide = param; else param = nOldGlbVolSlide;
+-				if (((param & 0x0F) == 0x0F) && (param & 0xF0))
+-				{
+-					param >>= 4;
+-					if (m_nType != MOD_TYPE_IT) param <<= 1;
+-					nGlbVol += param << 1;
+-				} else
+-				if (((param & 0xF0) == 0xF0) && (param & 0x0F))
+-				{
+-					param = (param & 0x0F) << 1;
+-					if (m_nType != MOD_TYPE_IT) param <<= 1;
+-					nGlbVol -= param;
+-				} else
+-				if (param & 0xF0)
+-				{
+-					param >>= 4;
+-					param <<= 1;
+-					if (m_nType != MOD_TYPE_IT) param <<= 1;
+-					nGlbVol += param * nMusicSpeed;
+-				} else
+-				{
+-					param = (param & 0x0F) << 1;
+-					if (m_nType != MOD_TYPE_IT) param <<= 1;
+-					nGlbVol -= param * nMusicSpeed;
+-				}
+-				if (nGlbVol < 0) nGlbVol = 0;
+-				if (nGlbVol > 256) nGlbVol = 256;
+-				break;
+-			case CMD_CHANNELVOLUME:
+-				if (param <= 64) chnvols[nChn] = param;
+-				break;
+-			case CMD_CHANNELVOLSLIDE:
+-				if (param) oldparam[nChn] = param; else param = oldparam[nChn];
+-				pChn->nOldChnVolSlide = param;
+-				if (((param & 0x0F) == 0x0F) && (param & 0xF0))
+-				{
+-					param = (param >> 4) + chnvols[nChn];
+-				} else
+-				if (((param & 0xF0) == 0xF0) && (param & 0x0F))
+-				{
+-					if (chnvols[nChn] > (int)(param & 0x0F)) param = chnvols[nChn] - (param & 0x0F);
+-					else param = 0;
+-				} else
+-				if (param & 0x0F)
+-				{
+-					param = (param & 0x0F) * nMusicSpeed;
+-					param = (chnvols[nChn] > param) ? chnvols[nChn] - param : 0;
+-				} else param = ((param & 0xF0) >> 4) * nMusicSpeed + chnvols[nChn];
+-				if (param > 64) param = 64;
+-				chnvols[nChn] = param;
+-				break;
+-			}
+-		}
+-		nSpeedCount += nMusicSpeed;
+-		dwElapsedTime += (2500 * nSpeedCount) / nMusicTempo;
+-	}
+-EndMod:
+-	if ((bAdjust) && (!bTotal))
+-	{
+-		m_nGlobalVolume = nGlbVol;
+-		m_nOldGlbVolSlide = nOldGlbVolSlide;
+-		for (UINT n=0; n<m_nChannels; n++)
+-		{
+-			Chn[n].nGlobalVol = chnvols[n];
+-			if (notes[n]) Chn[n].nNewNote = notes[n];
+-			if (instr[n]) Chn[n].nNewIns = instr[n];
+-			if (vols[n] != 0xFF)
+-			{
+-				if (vols[n] > 64) vols[n] = 64;
+-				Chn[n].nVolume = vols[n] << 2;
+-			}
+-		}
+-	}
+-	return (dwElapsedTime+500) / 1000;
+-}
+-
+-
+-//////////////////////////////////////////////////////////////////////////////////////////////////
+-// Effects
+-
+-void CSoundFile::InstrumentChange(MODCHANNEL *pChn, UINT instr, BOOL bPorta, BOOL bUpdVol, BOOL bResetEnv)
+-//--------------------------------------------------------------------------------------------------------
+-{
+-	BOOL bInstrumentChanged = FALSE;
+-
+-	if (instr >= MAX_INSTRUMENTS) return;
+-	INSTRUMENTHEADER *penv = (m_dwSongFlags & SONG_INSTRUMENTMODE) ? Headers[instr] : NULL;
+-	MODINSTRUMENT *psmp = &Ins[instr];
+-	UINT note = pChn->nNewNote;
+-	if ((penv) && (note) && (note <= 128))
+-	{
+-		if (penv->NoteMap[note-1] >= 0xFE) return;
+-		UINT n = penv->Keyboard[note-1];
+-		psmp = ((n) && (n < MAX_SAMPLES)) ? &Ins[n] : NULL;
+-		pChn->dwFlags &= ~CHN_SUSTAINLOOP; // turn off sustain
+-	} else
+-	if (m_dwSongFlags & SONG_INSTRUMENTMODE)
+-	{
+-		if (note >= 0xFE) return;
+-		psmp = NULL;
+-	}
+-	// Update Volume
+-	if (bUpdVol) pChn->nVolume = (psmp) ? psmp->nVolume : 0;
+-	// bInstrumentChanged is used for IT carry-on env option
+-	if (penv != pChn->pHeader)
+-	{
+-		bInstrumentChanged = TRUE;
+-		pChn->pHeader = penv;
+-	} else
+-	// Special XM hack
+-	if ((bPorta) && (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) && (penv)
+-	 && (pChn->pInstrument) && (psmp != pChn->pInstrument))
+-	{
+-		// FT2 doesn't change the sample in this case,
+-		// but still uses the sample info from the old one (bug?)
+-		return;
+-	}
+-	// Instrument adjust
+-	pChn->nNewIns = 0;
+-	if (psmp)
+-	{
+-		psmp->played = 1;
+-		if (penv)
+-		{
+-			penv->played = 1;
+-			pChn->nInsVol = (psmp->nGlobalVol * penv->nGlobalVol) >> 7;
+-			if (penv->dwFlags & ENV_SETPANNING) pChn->nPan = penv->nPan;
+-			pChn->nNNA = penv->nNNA;
+-		} else
+-		{
+-			pChn->nInsVol = psmp->nGlobalVol;
+-		}
+-		if (psmp->uFlags & CHN_PANNING) pChn->nPan = psmp->nPan;
+-	}
+-	// Reset envelopes
+-	if (bResetEnv)
+-	{
+-		if ((!bPorta) || (!(m_nType & MOD_TYPE_IT)) || (m_dwSongFlags & SONG_ITCOMPATMODE)
+-		 || (!pChn->nLength) || ((pChn->dwFlags & CHN_NOTEFADE) && (!pChn->nFadeOutVol)))
+-		{
+-			pChn->dwFlags |= CHN_FASTVOLRAMP;
+-			if ((m_nType & MOD_TYPE_IT) && (!bInstrumentChanged) && (penv) && (!(pChn->dwFlags & (CHN_KEYOFF|CHN_NOTEFADE))))
+-			{
+-				if (!(penv->dwFlags & ENV_VOLCARRY)) pChn->nVolEnvPosition = 0;
+-				if (!(penv->dwFlags & ENV_PANCARRY)) pChn->nPanEnvPosition = 0;
+-				if (!(penv->dwFlags & ENV_PITCHCARRY)) pChn->nPitchEnvPosition = 0;
+-			} else
+-			{
+-				pChn->nVolEnvPosition = 0;
+-				pChn->nPanEnvPosition = 0;
+-				pChn->nPitchEnvPosition = 0;
+-			}
+-			pChn->nAutoVibDepth = 0;
+-			pChn->nAutoVibPos = 0;
+-		} else
+-		if ((penv) && (!(penv->dwFlags & ENV_VOLUME)))
+-		{
+-			pChn->nVolEnvPosition = 0;
+-			pChn->nAutoVibDepth = 0;
+-			pChn->nAutoVibPos = 0;
+-		}
+-	}
+-	// Invalid sample ?
+-	if (!psmp)
+-	{
+-		pChn->pInstrument = NULL;
+-		pChn->nInsVol = 0;
+-		return;
+-	}
+-	// Tone-Portamento doesn't reset the pingpong direction flag
+-	if ((bPorta) && (psmp == pChn->pInstrument))
+-	{
+-		if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT)) return;
+-		pChn->dwFlags &= ~(CHN_KEYOFF|CHN_NOTEFADE);
+-		pChn->dwFlags = (pChn->dwFlags & (0xFFFFFF00 | CHN_PINGPONGFLAG)) | (psmp->uFlags);
+-	} else
+-	{
+-		pChn->dwFlags &= ~(CHN_KEYOFF|CHN_NOTEFADE|CHN_VOLENV|CHN_PANENV|CHN_PITCHENV);
+-		pChn->dwFlags = (pChn->dwFlags & 0xFFFFFF00) | (psmp->uFlags);
+-		if (penv)
+-		{
+-			if (penv->dwFlags & ENV_VOLUME) pChn->dwFlags |= CHN_VOLENV;
+-			if (penv->dwFlags & ENV_PANNING) pChn->dwFlags |= CHN_PANENV;
+-			if (penv->dwFlags & ENV_PITCH) pChn->dwFlags |= CHN_PITCHENV;
+-			if ((penv->dwFlags & ENV_PITCH) && (penv->dwFlags & ENV_FILTER))
+-			{
+-				if (!pChn->nCutOff) pChn->nCutOff = 0x7F;
+-			}
+-			if (penv->nIFC & 0x80) pChn->nCutOff = penv->nIFC & 0x7F;
+-			if (penv->nIFR & 0x80) pChn->nResonance = penv->nIFR & 0x7F;
+-		}
+-		pChn->nVolSwing = pChn->nPanSwing = 0;
+-	}
+-	pChn->pInstrument = psmp;
+-	pChn->nLength = psmp->nLength;
+-	pChn->nLoopStart = psmp->nLoopStart;
+-	pChn->nLoopEnd = psmp->nLoopEnd;
+-	pChn->nC4Speed = psmp->nC4Speed;
+-	pChn->pSample = psmp->pSample;
+-	pChn->nTranspose = psmp->RelativeTone;
+-	pChn->nFineTune = psmp->nFineTune;
+-	if (pChn->dwFlags & CHN_SUSTAINLOOP)
+-	{
+-		pChn->nLoopStart = psmp->nSustainStart;
+-		pChn->nLoopEnd = psmp->nSustainEnd;
+-		pChn->dwFlags |= CHN_LOOP;
+-		if (pChn->dwFlags & CHN_PINGPONGSUSTAIN) pChn->dwFlags |= CHN_PINGPONGLOOP;
+-	}
+-	if ((pChn->dwFlags & CHN_LOOP) && (pChn->nLoopEnd < pChn->nLength)) pChn->nLength = pChn->nLoopEnd;
+-}
+-
+-
+-void CSoundFile::NoteChange(UINT nChn, int note, BOOL bPorta, BOOL bResetEnv, BOOL bManual)
+-//-----------------------------------------------------------------------------------------
+-{
+-	if (note < 1) return;
+-	MODCHANNEL * const pChn = &Chn[nChn];
+-	MODINSTRUMENT *pins = pChn->pInstrument;
+-	INSTRUMENTHEADER *penv = (m_dwSongFlags & SONG_INSTRUMENTMODE) ? pChn->pHeader : NULL;
+-	if ((penv) && (note <= 0x80))
+-	{
+-		UINT n = penv->Keyboard[note - 1];
+-		if ((n) && (n < MAX_SAMPLES)) pins = &Ins[n];
+-		note = penv->NoteMap[note-1];
+-		pChn->dwFlags &= ~CHN_SUSTAINLOOP; // turn off sustain
+-	}
+-	// Key Off
+-	if (note >= 0x80)	// 0xFE or invalid note => key off
+-	{
+-                // technically this is "wrong", as anything besides ^^^, ===, and a valid note
+-		// should cause a note fade... (oh well, it's just a quick hack anyway.)
+-                if (note == 0xFD) {
+-			pChn->dwFlags |= CHN_NOTEFADE;
+-                        return;
+-                }
+-                
+-		// Key Off
+-		KeyOff(nChn);
+-		// Note Cut
+-		if (note == 0xFE)
+-		{
+-			pChn->dwFlags |= (CHN_NOTEFADE|CHN_FASTVOLRAMP);
+-			if ((!(m_nType & MOD_TYPE_IT)) || (m_dwSongFlags & SONG_INSTRUMENTMODE))
+-				pChn->nVolume = 0;
+-			pChn->nFadeOutVol = 0;
+-		}
+-		return;
+-	}
+-	if (!pins) return;
+-	if ((!bPorta) && (m_nType & (MOD_TYPE_XM|MOD_TYPE_MED|MOD_TYPE_MT2)))
+-	{
+-		pChn->nTranspose = pins->RelativeTone;
+-		pChn->nFineTune = pins->nFineTune;
+-	}
+-	if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2|MOD_TYPE_MED)) note += pChn->nTranspose;
+-	if (note < 1) note = 1;
+-	if (note > 132) note = 132;
+-	pChn->nNote = note;
+-	if ((!bPorta) || (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT))) pChn->nNewIns = 0;
+-	UINT period = GetPeriodFromNote(note, pChn->nFineTune, pChn->nC4Speed);
+-	if (period)
+-	{
+-		if ((!bPorta) || (!pChn->nPeriod)) pChn->nPeriod = period;
+-		pChn->nPortamentoDest = period;
+-		if ((!bPorta) || ((!pChn->nLength) && (!(m_nType & MOD_TYPE_S3M))))
+-		{
+-			pChn->pInstrument = pins;
+-			pChn->pSample = pins->pSample;
+-			pChn->nLength = pins->nLength;
+-			pChn->nLoopEnd = pins->nLength;
+-			pChn->nLoopStart = 0;
+-			pChn->dwFlags = (pChn->dwFlags & 0xFFFFFF00) | (pins->uFlags);
+-			if (pChn->dwFlags & CHN_SUSTAINLOOP)
+-			{
+-				pChn->nLoopStart = pins->nSustainStart;
+-				pChn->nLoopEnd = pins->nSustainEnd;
+-				pChn->dwFlags &= ~CHN_PINGPONGLOOP;
+-				pChn->dwFlags |= CHN_LOOP;
+-				if (pChn->dwFlags & CHN_PINGPONGSUSTAIN) pChn->dwFlags |= CHN_PINGPONGLOOP;
+-				if (pChn->nLength > pChn->nLoopEnd) pChn->nLength = pChn->nLoopEnd;
+-			} else
+-			if (pChn->dwFlags & CHN_LOOP)
+-			{
+-				pChn->nLoopStart = pins->nLoopStart;
+-				pChn->nLoopEnd = pins->nLoopEnd;
+-				if (pChn->nLength > pChn->nLoopEnd) pChn->nLength = pChn->nLoopEnd;
+-			}
+-			pChn->nPos = 0;
+-			pChn->nPosLo = 0;
+-			if (pChn->nVibratoType < 4) pChn->nVibratoPos = ((m_nType & MOD_TYPE_IT) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))) ? 0x10 : 0;
+-			if (pChn->nTremoloType < 4) pChn->nTremoloPos = 0;
+-		}
+-		if (pChn->nPos >= pChn->nLength) pChn->nPos = pChn->nLoopStart;
+-	} else bPorta = FALSE;
+-	if ((!bPorta) || (!(m_nType & MOD_TYPE_IT))
+-	 || ((pChn->dwFlags & CHN_NOTEFADE) && (!pChn->nFadeOutVol))
+-	 || ((m_dwSongFlags & SONG_ITCOMPATMODE) && (pChn->nRowInstr)))
+-	{
+-		if ((m_nType & MOD_TYPE_IT) && (pChn->dwFlags & CHN_NOTEFADE) && (!pChn->nFadeOutVol))
+-		{
+-			pChn->nVolEnvPosition = 0;
+-			pChn->nPanEnvPosition = 0;
+-			pChn->nPitchEnvPosition = 0;
+-			pChn->nAutoVibDepth = 0;
+-			pChn->nAutoVibPos = 0;
+-			pChn->dwFlags &= ~CHN_NOTEFADE;
+-			pChn->nFadeOutVol = 65536;
+-		}
+-		if ((!bPorta) || (!(m_dwSongFlags & SONG_ITCOMPATMODE)) || (pChn->nRowInstr))
+-		{
+-			if ((!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))) || (pChn->nRowInstr))
+-			{
+-				pChn->dwFlags &= ~CHN_NOTEFADE;
+-				pChn->nFadeOutVol = 65536;
+-			}
+-		}
+-	}
+-	pChn->dwFlags &= ~(CHN_EXTRALOUD|CHN_KEYOFF);
+-	// Enable Ramping
+-	if (!bPorta)
+-	{
+-		pChn->nVUMeter = 0x100;
+-		pChn->nLeftVU = pChn->nRightVU = 0xFF;
+-		pChn->dwFlags &= ~CHN_FILTER;
+-		pChn->dwFlags |= CHN_FASTVOLRAMP;
+-		pChn->nRetrigCount = 0;
+-		pChn->nTremorCount = 0;
+-		if (bResetEnv)
+-		{
+-			pChn->nVolSwing = pChn->nPanSwing = 0;
+-			if (penv)
+-			{
+-				if (!(penv->dwFlags & ENV_VOLCARRY)) pChn->nVolEnvPosition = 0;
+-				if (!(penv->dwFlags & ENV_PANCARRY)) pChn->nPanEnvPosition = 0;
+-				if (!(penv->dwFlags & ENV_PITCHCARRY)) pChn->nPitchEnvPosition = 0;
+-				if (m_nType & MOD_TYPE_IT)
+-				{
+-					// Volume Swing
+-					if (penv->nVolSwing)
+-					{
+-						/* this was wrong */
+-						int d = ((LONG)penv->nVolSwing*(LONG)((rand() & 0xFF) - 0x7F)) / 256;
+-						pChn->nVolSwing = (signed short)((d * pChn->nVolume + 1)/256);
+-					}
+-					// Pan Swing
+-					if (penv->nPanSwing)
+-					{
+-						int d = ((LONG)penv->nPanSwing*(LONG)((rand() & 0xFF) - 0x7F)) / 128;
+-						pChn->nPanSwing = (signed short)d;
+-					}
+-				}
+-			}
+-			pChn->nAutoVibDepth = 0;
+-			pChn->nAutoVibPos = 0;
+-		}
+-		pChn->nLeftVol = pChn->nRightVol = 0;
+-		BOOL bFlt = (m_dwSongFlags & SONG_MPTFILTERMODE) ? FALSE : TRUE;
+-		// Setup Initial Filter for this note
+-		if (penv)
+-		{
+-			if (penv->nIFR & 0x80) { pChn->nResonance = penv->nIFR & 0x7F; bFlt = TRUE; }
+-			if (penv->nIFC & 0x80) { pChn->nCutOff = penv->nIFC & 0x7F; bFlt = TRUE; }
+-		} else
+-		{
+-			pChn->nVolSwing = pChn->nPanSwing = 0;
+-		}
+-#ifndef NO_FILTER
+-		if ((pChn->nCutOff < 0x7F) && (bFlt)) SetupChannelFilter(pChn, TRUE);
+-#endif // NO_FILTER
+-	}
+-	// Special case for MPT
+-	if (bManual) pChn->dwFlags &= ~CHN_MUTE;
+-	if (((pChn->dwFlags & CHN_MUTE) && (gdwSoundSetup & SNDMIX_MUTECHNMODE))
+-	    || ((pChn->pInstrument) && (pChn->pInstrument->uFlags & CHN_MUTE) && (!bManual))
+-	    || ((m_dwSongFlags & SONG_INSTRUMENTMODE) && (pChn->pHeader)
+-	        && (pChn->pHeader->dwFlags & ENV_MUTE) && (!bManual)))
+-	{
+-		if (!bManual) pChn->nPeriod = 0;
+-	}
+-}
+-
+-
+-UINT CSoundFile::GetNNAChannel(UINT nChn)
+-//---------------------------------------------
+-{
+-	MODCHANNEL *pChn = &Chn[nChn];
+-	// Check for empty channel
+-	MODCHANNEL *pi = &Chn[m_nChannels];
+-	for (UINT i=m_nChannels; i<MAX_CHANNELS; i++, pi++) {
+-		if (!pi->nLength) {
+-			if (pi->dwFlags & CHN_MUTE) {
+-				if (pi->dwFlags & CHN_NNAMUTE) {
+-					pi->dwFlags &= ~(CHN_NNAMUTE|CHN_MUTE);
+-				} else {
+-					/* this channel is muted; skip */
+-					continue;
+-				}
+-			}
+-			return i;
+-		}
+-	}
+-	if (!pChn->nFadeOutVol) return 0;
+-	// All channels are used: check for lowest volume
+-	UINT result = 0;
+-	DWORD vol = 64*65536;	// 25%
+-	int envpos = 0xFFFFFF;
+-	const MODCHANNEL *pj = &Chn[m_nChannels];
+-	for (UINT j=m_nChannels; j<MAX_CHANNELS; j++, pj++)
+-	{
+-		if (!pj->nFadeOutVol) return j;
+-		DWORD v = pj->nVolume;
+-		if (pj->dwFlags & CHN_NOTEFADE)
+-			v = v * pj->nFadeOutVol;
+-		else
+-			v <<= 16;
+-		if (pj->dwFlags & CHN_LOOP) v >>= 1;
+-		if ((v < vol) || ((v == vol) && (pj->nVolEnvPosition > envpos)))
+-		{
+-			envpos = pj->nVolEnvPosition;
+-			vol = v;
+-			result = j;
+-		}
+-	}
+-	if (result) {
+-		/* unmute new nna channel */
+-		Chn[result].dwFlags &= ~(CHN_MUTE|CHN_NNAMUTE);
+-	}
+-	return result;
+-}
+-
+-
+-void CSoundFile::CheckNNA(UINT nChn, UINT instr, int note, BOOL bForceCut)
+-//------------------------------------------------------------------------
+-{
+-        MODCHANNEL *p;
+-	MODCHANNEL *pChn = &Chn[nChn];
+-	INSTRUMENTHEADER *penv = (m_dwSongFlags & SONG_INSTRUMENTMODE) ? pChn->pHeader : NULL;
+-	INSTRUMENTHEADER *pHeader;
+-	signed char *pSample;
+-	if (note > 0x80) note = 0;
+-	if (note < 1) return;
+-	// Always NNA cut - using
+-	if ((!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MT2))) || (!(m_dwSongFlags & SONG_INSTRUMENTMODE)) || (bForceCut))
+-	{
+-		if ((m_dwSongFlags & SONG_CPUVERYHIGH)
+-		 || (!pChn->nLength) || (pChn->dwFlags & CHN_MUTE)
+-		 || ((!pChn->nLeftVol) && (!pChn->nRightVol))) return;
+-		UINT n = GetNNAChannel(nChn);
+-		if (!n) return;
+-		p = &Chn[n];
+-		// Copy Channel
+-		*p = *pChn;
+-		p->dwFlags &= ~(CHN_VIBRATO|CHN_TREMOLO|CHN_PANBRELLO|CHN_PORTAMENTO);
+-		p->nMasterChn = nChn+1;
+-		p->nCommand = 0;
+-		// Cut the note
+-		p->nFadeOutVol = 0;
+-		p->dwFlags |= (CHN_NOTEFADE|CHN_FASTVOLRAMP);
+-		// Stop this channel
+-		pChn->nLength = pChn->nPos = pChn->nPosLo = 0;
+-		pChn->nROfs = pChn->nLOfs = 0;
+-		pChn->nLeftVol = pChn->nRightVol = 0;
+-		return;
+-	}
+-	if (instr >= MAX_INSTRUMENTS) instr = 0;
+-	pSample = pChn->pSample;
+-	pHeader = pChn->pHeader;
+-	if ((instr) && (note))
+-	{
+-		pHeader = (m_dwSongFlags & SONG_INSTRUMENTMODE) ? Headers[instr] : NULL;
+-		if (pHeader)
+-		{
+-			UINT n = 0;
+-			if (note <= 0x80)
+-			{
+-				n = pHeader->Keyboard[note-1];
+-				note = pHeader->NoteMap[note-1];
+-				if ((n) && (n < MAX_SAMPLES)) pSample = Ins[n].pSample;
+-			}
+-		} else pSample = NULL;
+-	}
+-	if (!penv) return;
+-	p = pChn;
+-	for (UINT i=nChn; i<MAX_CHANNELS; p++, i++)
+-	if ((i >= m_nChannels) || (p == pChn))
+-	{
+-		if (((p->nMasterChn == nChn+1) || (p == pChn)) && (p->pHeader))
+-		{
+-			BOOL bOk = FALSE;
+-			// Duplicate Check Type
+-			switch(p->pHeader->nDCT)
+-			{
+-			// Note
+-			case DCT_NOTE:
+-				if ((note) && ((int)p->nNote == note) && (pHeader == p->pHeader)) bOk = TRUE;
+-				break;
+-			// Sample
+-			case DCT_SAMPLE:
+-				if ((pSample) && (pSample == p->pSample)) bOk = TRUE;
+-				break;
+-			// Instrument
+-			case DCT_INSTRUMENT:
+-				if (pHeader == p->pHeader) bOk = TRUE;
+-				break;
+-			}
+-			// Duplicate Note Action
+-			if (bOk)
+-			{
+-				switch(p->pHeader->nDNA)
+-				{
+-				// Cut
+-				case DNA_NOTECUT:
+-					KeyOff(i);
+-					p->nVolume = 0;
+-					break;
+-				// Note Off
+-				case DNA_NOTEOFF:
+-					KeyOff(i);
+-					break;
+-				// Note Fade
+-				case DNA_NOTEFADE:
+-					p->dwFlags |= CHN_NOTEFADE;
+-					break;
+-				}
+-				if (!p->nVolume)
+-				{
+-					p->nFadeOutVol = 0;
+-					p->dwFlags |= (CHN_NOTEFADE|CHN_FASTVOLRAMP);
+-				}
+-			}
+-		}
+-	}
+-	if (pChn->dwFlags & CHN_MUTE) return;
+-	// New Note Action
+-	if ((pChn->nVolume) && (pChn->nLength))
+-	{
+-		UINT n = GetNNAChannel(nChn);
+-		if (n)
+-		{
+-			p = &Chn[n];
+-			// Copy Channel
+-			*p = *pChn;
+-			p->dwFlags &= ~(CHN_VIBRATO|CHN_TREMOLO|CHN_PANBRELLO|CHN_PORTAMENTO);
+-			p->nMasterChn = nChn+1;
+-			p->nCommand = 0;
+-			// Key Off the note
+-			switch(pChn->nNNA)
+-			{
+-			case NNA_NOTEOFF:	KeyOff(n); break;
+-			case NNA_NOTECUT:
+-				p->nFadeOutVol = 0;
+-			case NNA_NOTEFADE:	p->dwFlags |= CHN_NOTEFADE; break;
+-			}
+-			if (!p->nVolume)
+-			{
+-				p->nFadeOutVol = 0;
+-				p->dwFlags |= (CHN_NOTEFADE|CHN_FASTVOLRAMP);
+-			}
+-			// Stop this channel
+-			pChn->nLength = pChn->nPos = pChn->nPosLo = 0;
+-			pChn->nROfs = pChn->nLOfs = 0;
+-		}
+-	}
+-}
+-
+-
+-BOOL CSoundFile::ProcessEffects()
+-//-------------------------------
+-{
+-	int nBreakRow = -1, nPosJump = -1, nPatLoopRow = -1;
+-	MODCHANNEL *pChn = Chn;
+-	for (UINT nChn=0; nChn<m_nChannels; nChn++, pChn++)
+-	{
+-		pChn->nCommand=0;
+-
+-		UINT instr = pChn->nRowInstr;
+-		UINT volcmd = pChn->nRowVolCmd;
+-		UINT vol = pChn->nRowVolume;
+-		UINT cmd = pChn->nRowCommand;
+-		UINT param = pChn->nRowParam;
+-		BOOL bPorta = ((cmd != CMD_TONEPORTAMENTO) && (cmd != CMD_TONEPORTAVOL) && (volcmd != VOLCMD_TONEPORTAMENTO)) ? FALSE : TRUE;
+-		UINT nStartTick = pChn->nTickStart;
+-
+-		pChn->dwFlags &= ~CHN_FASTVOLRAMP;
+-		// Process special effects (note delay, pattern delay, pattern loop)
+-		if (((cmd == CMD_MODCMDEX) || (cmd == CMD_S3MCMDEX)))
+-		{
+-			if ((!param) && (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT))) param = pChn->nOldCmdEx; else pChn->nOldCmdEx = param;
+-			// Note Delay ?
+-			if ((param & 0xF0) == 0xD0)
+-			{
+-				nStartTick = param & 0x0F;
+-			} else
+-			if (!m_nTickCount)
+-			{
+-				// Pattern Loop ?
+-				if ((((param & 0xF0) == 0x60) && (cmd == CMD_MODCMDEX))
+-				 || (((param & 0xF0) == 0xB0) && (cmd == CMD_S3MCMDEX)))
+-				{
+-					int nloop = PatternLoop(pChn, param & 0x0F);
+-					if (nloop >= 0) nPatLoopRow = nloop;
+-				} else
+-				// Pattern Delay
+-				if ((param & 0xF0) == 0xE0)
+-				{
+-					m_nPatternDelay = param & 0x0F;
+-				}
+-			}
+-		}
+-
+-		// Handles note/instrument/volume changes
+-		if (m_nTickCount == nStartTick) // can be delayed by a note delay effect
+-		{
+-			UINT note = pChn->nRowNote;
+-			if (instr) pChn->nNewIns = instr;
+-			// XM: Key-Off + Sample == Note Cut
+-			if (m_nType & (MOD_TYPE_MOD|MOD_TYPE_XM|MOD_TYPE_MT2))
+-			{
+-				if ((note == 0xFF) && ((!pChn->pHeader) || (!(pChn->pHeader->dwFlags & ENV_VOLUME))))
+-				{
+-					pChn->dwFlags |= CHN_FASTVOLRAMP;
+-					pChn->nVolume = 0;
+-					note = instr = 0;
+-				}
+-			}
+-			if ((!note) && (instr))
+-			{
+-				if (m_dwSongFlags & SONG_INSTRUMENTMODE)
+-				{
+-					if (pChn->pInstrument) pChn->nVolume = pChn->pInstrument->nVolume;
+-					if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))
+-					{
+-						pChn->dwFlags |= CHN_FASTVOLRAMP;
+-						pChn->nVolEnvPosition = 0;
+-						pChn->nPanEnvPosition = 0;
+-						pChn->nPitchEnvPosition = 0;
+-						pChn->nAutoVibDepth = 0;
+-						pChn->nAutoVibPos = 0;
+-						pChn->dwFlags &= ~CHN_NOTEFADE;
+-						pChn->nFadeOutVol = 65536;
+-					}
+-				} else
+-				{
+-					if (instr < MAX_SAMPLES) pChn->nVolume = Ins[instr].nVolume;
+-				}
+-				if (!(m_nType & MOD_TYPE_IT)) instr = 0;
+-			}
+-			// Invalid Instrument ?
+-			if (instr >= MAX_INSTRUMENTS) instr = 0;
+-			// Note Cut/Off => ignore instrument
+-			if (note >= 0xFE) instr = 0;
+-			if ((note) && (note <= 128)) pChn->nNewNote = note;
+-			// New Note Action ? (not when paused!!!)
+-			if ((note) && (note <= 128) && (!bPorta))
+-			{
+-				CheckNNA(nChn, instr, note, FALSE);
+-			}
+-			// Instrument Change ?
+-			if (instr)
+-			{
+-				MODINSTRUMENT *psmp = pChn->pInstrument;
+-				InstrumentChange(pChn, instr, bPorta, TRUE);
+-				pChn->nNewIns = 0;
+-				// Special IT case: portamento+note causes sample change -> ignore portamento
+-				if ((m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT))
+-				 && (psmp != pChn->pInstrument) && (note) && (note < 0x80))
+-				{
+-					bPorta = FALSE;
+-				}
+-			}
+-			// New Note ?
+-			if (note)
+-			{
+-				if ((!instr) && (pChn->nNewIns) && (note < 0x80))
+-				{
+-					InstrumentChange(pChn, pChn->nNewIns, bPorta, FALSE, (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) ? FALSE : TRUE);
+-					pChn->nNewIns = 0;
+-				}
+-				NoteChange(nChn, note, bPorta, (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) ? FALSE : TRUE);
+-				if ((bPorta) && (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) && (instr))
+-				{
+-					pChn->dwFlags |= CHN_FASTVOLRAMP;
+-					pChn->nVolEnvPosition = 0;
+-					pChn->nPanEnvPosition = 0;
+-					pChn->nPitchEnvPosition = 0;
+-					pChn->nAutoVibDepth = 0;
+-					pChn->nAutoVibPos = 0;
+-				}
+-			}
+-			// Tick-0 only volume commands
+-			if (volcmd == VOLCMD_VOLUME)
+-			{
+-				if (vol > 64) vol = 64;
+-				pChn->nVolume = vol << 2;
+-				pChn->dwFlags |= CHN_FASTVOLRAMP;
+-			} else
+-			if (volcmd == VOLCMD_PANNING)
+-			{
+-				if (vol > 64) vol = 64;
+-				pChn->nPan = vol << 2;
+-				pChn->dwFlags |= CHN_FASTVOLRAMP;
+-				pChn->dwFlags &= ~CHN_SURROUND;
+-			}
+-		}
+-
+-		// Volume Column Effect (except volume & panning)
+-		if ((volcmd > VOLCMD_PANNING) && (m_nTickCount >= nStartTick))
+-		{
+-			if (volcmd == VOLCMD_TONEPORTAMENTO)
+-			{
+-				if (m_nType & MOD_TYPE_IT)
+-					TonePortamento(pChn, ImpulseTrackerPortaVolCmd[vol & 0x0F]);
+-				else
+-					TonePortamento(pChn, vol * 16);
+-			} else
+-			{
+-				if (vol) pChn->nOldVolParam = vol; else vol = pChn->nOldVolParam;
+-				switch(volcmd)
+-				{
+-				case VOLCMD_VOLSLIDEUP:
+-					VolumeSlide(pChn, vol << 4);
+-					break;
+-
+-				case VOLCMD_VOLSLIDEDOWN:
+-					VolumeSlide(pChn, vol);
+-					break;
+-
+-				case VOLCMD_FINEVOLUP:
+-					if (m_nType & MOD_TYPE_IT)
+-					{
+-						if (m_nTickCount == nStartTick) VolumeSlide(pChn, (vol << 4) | 0x0F);
+-					} else
+-						FineVolumeUp(pChn, vol);
+-					break;
+-
+-				case VOLCMD_FINEVOLDOWN:
+-					if (m_nType & MOD_TYPE_IT)
+-					{
+-						if (m_nTickCount == nStartTick) VolumeSlide(pChn, 0xF0 | vol);
+-					} else
+-						FineVolumeDown(pChn, vol);
+-					break;
+-
+-				case VOLCMD_VIBRATOSPEED:
+-					Vibrato(pChn, vol << 4);
+-					break;
+-
+-				case VOLCMD_VIBRATO:
+-					Vibrato(pChn, vol);
+-					break;
+-
+-				case VOLCMD_PANSLIDELEFT:
+-					PanningSlide(pChn, vol);
+-					break;
+-
+-				case VOLCMD_PANSLIDERIGHT:
+-					PanningSlide(pChn, vol << 4);
+-					break;
+-
+-				case VOLCMD_PORTAUP:
+-					PortamentoUp(pChn, vol << 2);
+-					break;
+-
+-				case VOLCMD_PORTADOWN:
+-					PortamentoDown(pChn, vol << 2);
+-					break;
+-				}
+-			}
+-		}
+-
+-		// Effects
+-		if (cmd) switch (cmd)
+-		{
+-		// Set Volume
+-		case CMD_VOLUME:
+-			if (!m_nTickCount)
+-			{
+-				pChn->nVolume = (param < 64) ? param*4 : 256;
+-				pChn->dwFlags |= CHN_FASTVOLRAMP;
+-				for (UINT i=m_nChannels; i<MAX_CHANNELS; i++)
+-				{
+-					MODCHANNEL *c = &Chn[i];
+-					if (c->nMasterChn == (nChn+1)) {
+-						c->nVolume = pChn->nVolume;
+-						c->dwFlags |= CHN_FASTVOLRAMP;
+-					}
+-				}
+-			}
+-			break;
+-
+-		// Portamento Up
+-		case CMD_PORTAMENTOUP:
+-			if ((!param) && (m_nType & MOD_TYPE_MOD)) break;
+-			PortamentoUp(pChn, param);
+-			break;
+-
+-		// Portamento Down
+-		case CMD_PORTAMENTODOWN:
+-			if ((!param) && (m_nType & MOD_TYPE_MOD)) break;
+-			PortamentoDown(pChn, param);
+-			break;
+-
+-		// Volume Slide
+-		case CMD_VOLUMESLIDE:
+-			if ((param) || (m_nType != MOD_TYPE_MOD)) VolumeSlide(pChn, param);
+-			break;
+-
+-		// Tone-Portamento
+-		case CMD_TONEPORTAMENTO:
+-			TonePortamento(pChn, param);
+-			break;
+-
+-		// Tone-Portamento + Volume Slide
+-		case CMD_TONEPORTAVOL:
+-			if ((param) || (m_nType != MOD_TYPE_MOD)) VolumeSlide(pChn, param);
+-			TonePortamento(pChn, 0);
+-			break;
+-
+-		// Vibrato
+-		case CMD_VIBRATO:
+-			Vibrato(pChn, param);
+-			break;
+-
+-		// Vibrato + Volume Slide
+-		case CMD_VIBRATOVOL:
+-			if ((param) || (m_nType != MOD_TYPE_MOD)) VolumeSlide(pChn, param);
+-			Vibrato(pChn, 0);
+-			break;
+-
+-		// Set Speed
+-		case CMD_SPEED:
+-			if (!m_nTickCount) SetSpeed(param);
+-			break;
+-
+-		// Set Tempo
+-		case CMD_TEMPO:
+-			if (!m_nTickCount)
+-			{
+-				if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT))
+-				{
+-					if (param) pChn->nOldTempo = param; else param = pChn->nOldTempo;
+-				}
+-				SetTempo(param);
+-			} else {
+-                                param = pChn->nOldTempo; // this just got set on tick zero
+-                                
+-                                switch (param >> 4) {
+-                                case 0:
+-                                        m_nMusicTempo -= param & 0xf;
+-                                        if (m_nMusicTempo < 32)
+-                                                m_nMusicTempo = 32;
+-                                        break;
+-                                case 1:
+-                                        m_nMusicTempo += param & 0xf;
+-                                        if (m_nMusicTempo > 255)
+-                                                m_nMusicTempo = 255;
+-                                        break;
+-                                }
+-                        }
+-			break;
+-
+-		// Set Offset
+-		case CMD_OFFSET:
+-			if (m_nTickCount) break;
+-			if (param) pChn->nOldOffset = param; else param = pChn->nOldOffset;
+-			param <<= 8;
+-			param |= (UINT)(pChn->nOldHiOffset) << 16;
+-			if ((pChn->nRowNote) && (pChn->nRowNote < 0x80))
+-			{
+-				if (bPorta)
+-					pChn->nPos = param;
+-				else
+-					pChn->nPos += param;
+-				if (pChn->nPos >= pChn->nLength)
+-				{
+-					if (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)))
+-					{
+-						pChn->nPos = pChn->nLoopStart;
+-						if ((m_dwSongFlags & SONG_ITOLDEFFECTS) && (pChn->nLength > 4))
+-						{
+-							pChn->nPos = pChn->nLength - 2;
+-						}
+-					}
+-				}
+-			} else
+-			if ((param < pChn->nLength) && (m_nType & (MOD_TYPE_MTM|MOD_TYPE_DMF)))
+-			{
+-				pChn->nPos = param;
+-			}
+-			break;
+-
+-		// Arpeggio
+-		case CMD_ARPEGGIO:
+-			pChn->nCommand = CMD_ARPEGGIO;
+-			if ((m_nTickCount) || (!pChn->nPeriod) || (!pChn->nNote)) break;
+-			if ((!param) && (!(m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT)))) break;
+-			if (param) pChn->nArpeggio = param;
+-			break;
+-
+-		// Retrig
+-		case CMD_RETRIG:
+-			if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))
+-			{
+-				if (!(param & 0xF0)) param |= pChn->nRetrigParam & 0xF0;
+-				if (!(param & 0x0F)) param |= pChn->nRetrigParam & 0x0F;
+-				param |= 0x100; // increment retrig count on first row
+-			}
+-			// various bits of retriggery commented out here & below, reverting to old method...
+-			// -Storlek 04aug07
+-			// if (pChn->nRowNote && !m_nTickCount) pChn->nRetrigCount = 0;
+-			if (param) pChn->nRetrigParam = (BYTE)(param & 0xFF); else param = pChn->nRetrigParam;
+-			// pChn->nCommand = CMD_RETRIG;
+-			RetrigNote(nChn, param);
+-			break;
+-
+-		// Tremor
+-		case CMD_TREMOR:
+-			pChn->nCommand = CMD_TREMOR;
+-			if (m_nTickCount) break;
+-			if (param) pChn->nTremorParam = param;
+-			break;
+-
+-		// Set Global Volume
+-		case CMD_GLOBALVOLUME:
+-			if (m_nTickCount) break;
+-			if (m_nType != MOD_TYPE_IT) param <<= 1;
+-			if (param > 128) param = 128;
+-			m_nGlobalVolume = param << 1;
+-			break;
+-
+-		// Global Volume Slide
+-		case CMD_GLOBALVOLSLIDE:
+-			GlobalVolSlide(param);
+-			break;
+-
+-		// Set 8-bit Panning
+-		case CMD_PANNING8:
+-			if (m_nTickCount) break;
+-			if (!(m_dwSongFlags & SONG_SURROUNDPAN)) pChn->dwFlags &= ~CHN_SURROUND;
+-			if (m_nType & (MOD_TYPE_IT|MOD_TYPE_XM|MOD_TYPE_MT2))
+-			{
+-				pChn->nPan = param;
+-			} else
+-			if (param <= 0x80)
+-			{
+-				pChn->nPan = param << 1;
+-			} else
+-			if (param == 0xA4)
+-			{
+-				pChn->dwFlags |= CHN_SURROUND;
+-				pChn->nPan = 0x80;
+-			}
+-			pChn->dwFlags |= CHN_FASTVOLRAMP;
+-			break;
+-
+-		// Panning Slide
+-		case CMD_PANNINGSLIDE:
+-			PanningSlide(pChn, param);
+-			break;
+-
+-		// Tremolo
+-		case CMD_TREMOLO:
+-			Tremolo(pChn, param);
+-			break;
+-
+-		// Fine Vibrato
+-		case CMD_FINEVIBRATO:
+-			FineVibrato(pChn, param);
+-			break;
+-
+-		// MOD/XM Exx Extended Commands
+-		case CMD_MODCMDEX:
+-			ExtendedMODCommands(nChn, param);
+-			break;
+-
+-		// S3M/IT Sxx Extended Commands
+-		case CMD_S3MCMDEX:
+-			ExtendedS3MCommands(nChn, param);
+-			break;
+-
+-		// Key Off
+-		case CMD_KEYOFF:
+-			if (!m_nTickCount) KeyOff(nChn);
+-			break;
+-
+-		// Extra-fine porta up/down
+-		case CMD_XFINEPORTAUPDOWN:
+-			switch(param & 0xF0)
+-			{
+-			case 0x10: ExtraFinePortamentoUp(pChn, param & 0x0F); break;
+-			case 0x20: ExtraFinePortamentoDown(pChn, param & 0x0F); break;
+-			// Modplug XM Extensions
+-			case 0x50:
+-			case 0x60:
+-			case 0x70:
+-			case 0x90:
+-			case 0xA0: ExtendedS3MCommands(nChn, param); break;
+-			}
+-			break;
+-
+-		// Set Channel Global Volume
+-		case CMD_CHANNELVOLUME:
+-			if (m_nTickCount) break;
+-			if (param <= 64)
+-			{
+-				pChn->nGlobalVol = param;
+-				pChn->dwFlags |= CHN_FASTVOLRAMP;
+-				for (UINT i=m_nChannels; i<MAX_CHANNELS; i++)
+-				{
+-					MODCHANNEL *c = &Chn[i];
+-					if (c->nMasterChn == (nChn+1)) {
+-						c->nGlobalVol = param;
+-						c->dwFlags |= CHN_FASTVOLRAMP;
+-					}
+-				}
+-			}
+-			break;
+-
+-		// Channel volume slide
+-		case CMD_CHANNELVOLSLIDE:
+-			{
+-				int saw_self = 0;
+-
+-				for (UINT i=m_nChannels; i<MAX_CHANNELS; i++)
+-				{
+-					MODCHANNEL *c = &Chn[i];
+-					if (c->nMasterChn == (nChn+1)) {
+-						if (c == pChn) saw_self = 1;
+-						ChannelVolSlide(c, param);
+-					}
+-				}
+-				if (!saw_self) {
+-					ChannelVolSlide(pChn, param);
+-				}
+-			}
+-			
+-			break;
+-
+-		// Panbrello (IT)
+-		case CMD_PANBRELLO:
+-			Panbrello(pChn, param);
+-			break;
+-
+-		// Set Envelope Position
+-		case CMD_SETENVPOSITION:
+-			if (!m_nTickCount)
+-			{
+-				pChn->nVolEnvPosition = param;
+-				pChn->nPanEnvPosition = param;
+-				pChn->nPitchEnvPosition = param;
+-				if ((m_dwSongFlags & SONG_INSTRUMENTMODE) && pChn->pHeader)
+-				{
+-					INSTRUMENTHEADER *penv = pChn->pHeader;
+-					if ((pChn->dwFlags & CHN_PANENV) && (penv->PanEnv.nNodes) && ((int)param > penv->PanEnv.Ticks[penv->PanEnv.nNodes-1]))
+-					{
+-						pChn->dwFlags &= ~CHN_PANENV;
+-					}
+-				}
+-			}
+-			break;
+-
+-		// Position Jump
+-		case CMD_POSITIONJUMP:
+-			nPosJump = param;
+-			break;
+-
+-		// Pattern Break
+-		case CMD_PATTERNBREAK:
+-			nBreakRow = param;
+-			break;
+-
+-		// Midi Controller
+-		case CMD_MIDI:
+-			if (m_nTickCount) break;
+-			if (param < 0x80)
+-			{
+-				ProcessMidiMacro(nChn, &m_MidiCfg.szMidiSFXExt[pChn->nActiveMacro << 5], param);
+-			} else
+-			{
+-				ProcessMidiMacro(nChn, &m_MidiCfg.szMidiZXXExt[(param & 0x7F) << 5], 0);
+-			}
+-			break;
+-		}
+-	}
+-
+-	// Navigation Effects
+-	if (!m_nTickCount)
+-	{
+-		// Pattern Loop
+-		if (nPatLoopRow >= 0)
+-		{
+-			m_nNextPattern = m_nCurrentPattern;
+-			m_nNextRow = nPatLoopRow;
+-			if (m_nPatternDelay) m_nNextRow++;
+-		} else
+-		// Pattern Break / Position Jump only if no loop running
+-		if ((nBreakRow >= 0) || (nPosJump >= 0))
+-		{
+-			BOOL bNoLoop = FALSE;
+-			if (nPosJump < 0) nPosJump = m_nCurrentPattern+1;
+-			if (nBreakRow < 0) nBreakRow = 0;
+-			// Modplug Tracker & ModPlugin allow backward jumps
+-		#ifndef MODPLUG_FASTSOUNDLIB
+-			if ((nPosJump < (int)m_nCurrentPattern)
+-			 || ((nPosJump == (int)m_nCurrentPattern) && (nBreakRow <= (int)m_nRow)))
+-			{
+-				if (!IsValidBackwardJump(m_nCurrentPattern, m_nRow, nPosJump, nBreakRow))
+-				{
+-					if (m_nRepeatCount)
+-					{
+-						if (m_nRepeatCount > 0) m_nRepeatCount--;
+-					} else
+-					{
+-					#ifdef MODPLUG_TRACKER
+-						if (gdwSoundSetup & SNDMIX_NOBACKWARDJUMPS)
+-					#endif
+-						// Backward jump disabled
+-						bNoLoop = TRUE;
+-						//reset repeat count incase there are multiple loops.
+-						//(i.e. Unreal tracks)
+-						m_nRepeatCount = m_nInitialRepeatCount;
+-					}
+-				}
+-			}
+-		#endif	// MODPLUG_FASTSOUNDLIB
+-			if (((!bNoLoop) && (nPosJump < MAX_ORDERS))
+-			 && ((nPosJump != (int)m_nCurrentPattern) || (nBreakRow != (int)m_nRow)))
+-			{
+-				if (nPosJump != (int)m_nCurrentPattern)
+-				{
+-					for (UINT i=0; i<m_nChannels; i++) Chn[i].nPatternLoopCount = 0;
+-				}
+-				m_nNextPattern = nPosJump;
+-				m_nNextRow = (UINT)nBreakRow;
+-			}
+-		}
+-	}
+-	return TRUE;
+-}
+-
+-
+-////////////////////////////////////////////////////////////
+-// Channels effects
+-
+-void CSoundFile::PortamentoUp(MODCHANNEL *pChn, UINT param)
+-//---------------------------------------------------------
+-{
+-	if (param) pChn->nOldPortaUpDown = param; else param = pChn->nOldPortaUpDown;
+-	if (m_dwSongFlags & SONG_ITCOMPATMODE) pChn->nPortamentoSlide=param*4;
+-	else pChn->nPortamentoDest=0;
+-	if ((m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_STM)) && ((param & 0xF0) >= 0xE0))
+-	{
+-		if (param & 0x0F)
+-		{
+-			if ((param & 0xF0) == 0xF0)
+-			{
+-				FinePortamentoUp(pChn, param & 0x0F);
+-			} else
+-			if ((param & 0xF0) == 0xE0)
+-			{
+-				ExtraFinePortamentoUp(pChn, param & 0x0F);
+-			}
+-		}
+-		return;
+-	}
+-	// Regular Slide
+-	if (!(m_dwSongFlags & SONG_FIRSTTICK))
+-	{
+-		DoFreqSlide(pChn, -(int)(param * 4));
+-	}
+-}
+-
+-
+-void CSoundFile::PortamentoDown(MODCHANNEL *pChn, UINT param)
+-//-----------------------------------------------------------
+-{
+-	if (param) pChn->nOldPortaUpDown = param; else param = pChn->nOldPortaUpDown;
+-	if (m_dwSongFlags & SONG_ITCOMPATMODE) pChn->nPortamentoSlide=param*4;
+-	else pChn->nPortamentoDest=0;
+-	if ((m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_STM)) && ((param & 0xF0) >= 0xE0))
+-	{
+-		if (param & 0x0F)
+-		{
+-			if ((param & 0xF0) == 0xF0)
+-			{
+-				FinePortamentoDown(pChn, param & 0x0F);
+-			} else
+-			if ((param & 0xF0) == 0xE0)
+-			{
+-				ExtraFinePortamentoDown(pChn, param & 0x0F);
+-			}
+-		}
+-		return;
+-	}
+-	if (!(m_dwSongFlags & SONG_FIRSTTICK)) DoFreqSlide(pChn, (int)(param << 2));
+-}
+-
+-
+-void CSoundFile::FinePortamentoUp(MODCHANNEL *pChn, UINT param)
+-//-------------------------------------------------------------
+-{
+-	if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))
+-	{
+-		if (param) pChn->nOldFinePortaUpDown = param; else param = pChn->nOldFinePortaUpDown;
+-	}
+-	if (m_dwSongFlags & SONG_FIRSTTICK)
+-	{
+-		if ((pChn->nPeriod) && (param))
+-		{
+-			if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))))
+-			{
+-				pChn->nPeriod = _muldivr(pChn->nPeriod, LinearSlideDownTable[param & 0x0F], 65536);
+-			} else
+-			{
+-				pChn->nPeriod -= (int)(param * 4);
+-			}
+-			if (pChn->nPeriod < 1) pChn->nPeriod = 1;
+-		}
+-	}
+-}
+-
+-
+-void CSoundFile::FinePortamentoDown(MODCHANNEL *pChn, UINT param)
+-//---------------------------------------------------------------
+-{
+-	if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))
+-	{
+-		if (param) pChn->nOldFinePortaUpDown = param; else param = pChn->nOldFinePortaUpDown;
+-	}
+-	if (m_dwSongFlags & SONG_FIRSTTICK)
+-	{
+-		if ((pChn->nPeriod) && (param))
+-		{
+-			if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))))
+-			{
+-				pChn->nPeriod = _muldivr(pChn->nPeriod, LinearSlideUpTable[param & 0x0F], 65536);
+-			} else
+-			{
+-				pChn->nPeriod += (int)(param * 4);
+-			}
+-			if (pChn->nPeriod > 0xFFFF) pChn->nPeriod = 0xFFFF;
+-		}
+-	}
+-}
+-
+-
+-void CSoundFile::ExtraFinePortamentoUp(MODCHANNEL *pChn, UINT param)
+-//------------------------------------------------------------------
+-{
+-	if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))
+-	{
+-		if (param) pChn->nOldFinePortaUpDown = param; else param = pChn->nOldFinePortaUpDown;
+-	}
+-	if (m_dwSongFlags & SONG_FIRSTTICK)
+-	{
+-		if ((pChn->nPeriod) && (param))
+-		{
+-			if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))))
+-			{
+-				pChn->nPeriod = _muldivr(pChn->nPeriod, FineLinearSlideDownTable[param & 0x0F], 65536);
+-			} else
+-			{
+-				pChn->nPeriod -= (int)(param);
+-			}
+-			if (pChn->nPeriod < 1) pChn->nPeriod = 1;
+-		}
+-	}
+-}
+-
+-
+-void CSoundFile::ExtraFinePortamentoDown(MODCHANNEL *pChn, UINT param)
+-//--------------------------------------------------------------------
+-{
+-	if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))
+-	{
+-		if (param) pChn->nOldFinePortaUpDown = param; else param = pChn->nOldFinePortaUpDown;
+-	}
+-	if (m_dwSongFlags & SONG_FIRSTTICK)
+-	{
+-		if ((pChn->nPeriod) && (param))
+-		{
+-			if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))))
+-			{
+-				pChn->nPeriod = _muldivr(pChn->nPeriod, FineLinearSlideUpTable[param & 0x0F], 65536);
+-			} else
+-			{
+-				pChn->nPeriod += (int)(param);
+-			}
+-			if (pChn->nPeriod > 0xFFFF) pChn->nPeriod = 0xFFFF;
+-		}
+-	}
+-}
+-
+-
+-// Portamento Slide
+-void CSoundFile::TonePortamento(MODCHANNEL *pChn, UINT param)
+-//-----------------------------------------------------------
+-{
+-	if (param) pChn->nPortamentoSlide = param * 4;
+-	pChn->dwFlags |= CHN_PORTAMENTO;
+-	if ((pChn->nPeriod) && (pChn->nPortamentoDest) && (!(m_dwSongFlags & SONG_FIRSTTICK)))
+-	{
+-		if (pChn->nPeriod < pChn->nPortamentoDest)
+-		{
+-			LONG delta = (int)pChn->nPortamentoSlide;
+-			if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))))
+-			{
+-				UINT n = pChn->nPortamentoSlide >> 2;
+-				if (n > 255) n = 255;
+-				delta = _muldivr(pChn->nPeriod, LinearSlideUpTable[n], 65536) - pChn->nPeriod;
+-				if (delta < 1) delta = 1;
+-			}
+-			pChn->nPeriod += delta;
+-			if (pChn->nPeriod > pChn->nPortamentoDest) pChn->nPeriod = pChn->nPortamentoDest;
+-		} else
+-		if (pChn->nPeriod > pChn->nPortamentoDest)
+-		{
+-			LONG delta = - (int)pChn->nPortamentoSlide;
+-			if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))))
+-			{
+-				UINT n = pChn->nPortamentoSlide >> 2;
+-				if (n > 255) n = 255;
+-				delta = _muldivr(pChn->nPeriod, LinearSlideDownTable[n], 65536) - pChn->nPeriod;
+-				if (delta > -1) delta = -1;
+-			}
+-			pChn->nPeriod += delta;
+-			if (pChn->nPeriod < pChn->nPortamentoDest) pChn->nPeriod = pChn->nPortamentoDest;
+-		}
+-	}
+-}
+-
+-
+-void CSoundFile::Vibrato(MODCHANNEL *p, UINT param)
+-//-------------------------------------------------
+-{
+-	if (param & 0x0F) p->nVibratoDepth = (param & 0x0F) * 4;
+-	if (param & 0xF0) p->nVibratoSpeed = (param >> 4) & 0x0F;
+-	p->dwFlags |= CHN_VIBRATO;
+-}
+-
+-
+-void CSoundFile::FineVibrato(MODCHANNEL *p, UINT param)
+-//-----------------------------------------------------
+-{
+-	if (param & 0x0F) p->nVibratoDepth = param & 0x0F;
+-	if (param & 0xF0) p->nVibratoSpeed = (param >> 4) & 0x0F;
+-	p->dwFlags |= CHN_VIBRATO;
+-}
+-
+-
+-void CSoundFile::Panbrello(MODCHANNEL *p, UINT param)
+-//---------------------------------------------------
+-{
+-	if (param & 0x0F) p->nPanbrelloDepth = param & 0x0F;
+-	if (param & 0xF0) p->nPanbrelloSpeed = (param >> 4) & 0x0F;
+-	p->dwFlags |= CHN_PANBRELLO;
+-}
+-
+-
+-void CSoundFile::VolumeSlide(MODCHANNEL *pChn, UINT param)
+-//--------------------------------------------------------
+-{
+-	if (param) pChn->nOldVolumeSlide = param; else param = pChn->nOldVolumeSlide;
+-	LONG newvolume = pChn->nVolume;
+-	if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_STM|MOD_TYPE_AMF))
+-	{
+-		if ((param & 0x0F) == 0x0F)
+-		{
+-			if (param & 0xF0)
+-			{
+-				FineVolumeUp(pChn, (param >> 4));
+-				return;
+-			} else
+-			{
+-				if ((m_dwSongFlags & SONG_FIRSTTICK) && (!(m_dwSongFlags & SONG_FASTVOLSLIDES)))
+-				{
+-					newvolume -= 0x0F * 4;
+-				}
+-			}
+-		} else
+-		if ((param & 0xF0) == 0xF0)
+-		{
+-			if (param & 0x0F)
+-			{
+-				FineVolumeDown(pChn, (param & 0x0F));
+-				return;
+-			} else
+-			{
+-				if ((m_dwSongFlags & SONG_FIRSTTICK) && (!(m_dwSongFlags & SONG_FASTVOLSLIDES)))
+-				{
+-					newvolume += 0x0F * 4;
+-				}
+-			}
+-		}
+-	}
+-	if ((!(m_dwSongFlags & SONG_FIRSTTICK)) || (m_dwSongFlags & SONG_FASTVOLSLIDES))
+-	{
+-		if (param & 0x0F) newvolume -= (int)((param & 0x0F) * 4);
+-		else newvolume += (int)((param & 0xF0) >> 2);
+-		if (m_nType & MOD_TYPE_MOD) pChn->dwFlags |= CHN_FASTVOLRAMP;
+-	}
+-	if (newvolume < 0) newvolume = 0;
+-	if (newvolume > 256) newvolume = 256;
+-	pChn->nVolume = newvolume;
+-}
+-
+-
+-void CSoundFile::PanningSlide(MODCHANNEL *pChn, UINT param)
+-//---------------------------------------------------------
+-{
+-	LONG nPanSlide = 0;
+-	if (param) pChn->nOldPanSlide = param; else param = pChn->nOldPanSlide;
+-	if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_STM))
+-	{
+-		if (((param & 0x0F) == 0x0F) && (param & 0xF0))
+-		{
+-			if (m_dwSongFlags & SONG_FIRSTTICK)
+-			{
+-				param = (param & 0xF0) >> 2;
+-				nPanSlide = - (int)param;
+-			}
+-		} else
+-		if (((param & 0xF0) == 0xF0) && (param & 0x0F))
+-		{
+-			if (m_dwSongFlags & SONG_FIRSTTICK)
+-			{
+-				nPanSlide = (param & 0x0F) << 2;
+-			}
+-		} else
+-		{
+-			if (!(m_dwSongFlags & SONG_FIRSTTICK))
+-			{
+-				if (param & 0x0F) nPanSlide = (int)((param & 0x0F) << 2);
+-				else nPanSlide = -(int)((param & 0xF0) >> 2);
+-			}
+-		}
+-	} else
+-	{
+-		if (!(m_dwSongFlags & SONG_FIRSTTICK))
+-		{
+-			if (param & 0x0F) nPanSlide = -(int)((param & 0x0F) << 2);
+-			else nPanSlide = (int)((param & 0xF0) >> 2);
+-		}
+-	}
+-	if (nPanSlide)
+-	{
+-		nPanSlide += pChn->nPan;
+-		if (nPanSlide < 0) nPanSlide = 0;
+-		if (nPanSlide > 256) nPanSlide = 256;
+-		pChn->nPan = nPanSlide;
+-	}
+-	pChn->dwFlags &= ~CHN_SURROUND;
+-}
+-
+-
+-void CSoundFile::FineVolumeUp(MODCHANNEL *pChn, UINT param)
+-//---------------------------------------------------------
+-{
+-	if (param) pChn->nOldFineVolUpDown = param; else param = pChn->nOldFineVolUpDown;
+-	if (m_dwSongFlags & SONG_FIRSTTICK)
+-	{
+-		pChn->nVolume += param * 4;
+-		if (pChn->nVolume > 256) pChn->nVolume = 256;
+-		if (m_nType & MOD_TYPE_MOD) pChn->dwFlags |= CHN_FASTVOLRAMP;
+-	}
+-}
+-
+-
+-void CSoundFile::FineVolumeDown(MODCHANNEL *pChn, UINT param)
+-//-----------------------------------------------------------
+-{
+-	if (param) pChn->nOldFineVolUpDown = param; else param = pChn->nOldFineVolUpDown;
+-	if (m_dwSongFlags & SONG_FIRSTTICK)
+-	{
+-		pChn->nVolume -= param * 4;
+-		if (pChn->nVolume < 0) pChn->nVolume = 0;
+-		if (m_nType & MOD_TYPE_MOD) pChn->dwFlags |= CHN_FASTVOLRAMP;
+-	}
+-}
+-
+-
+-void CSoundFile::Tremolo(MODCHANNEL *p, UINT param)
+-//-------------------------------------------------
+-{
+-	if (param & 0x0F) p->nTremoloDepth = (param & 0x0F) << 2;
+-	if (param & 0xF0) p->nTremoloSpeed = (param >> 4) & 0x0F;
+-	p->dwFlags |= CHN_TREMOLO;
+-}
+-
+-
+-void CSoundFile::ChannelVolSlide(MODCHANNEL *pChn, UINT param)
+-//------------------------------------------------------------
+-{
+-	LONG nChnSlide = 0;
+-	if (param) pChn->nOldChnVolSlide = param; else param = pChn->nOldChnVolSlide;
+-	if (((param & 0x0F) == 0x0F) && (param & 0xF0))
+-	{
+-		if (m_dwSongFlags & SONG_FIRSTTICK) nChnSlide = param >> 4;
+-	} else
+-	if (((param & 0xF0) == 0xF0) && (param & 0x0F))
+-	{
+-		if (m_dwSongFlags & SONG_FIRSTTICK) nChnSlide = - (int)(param & 0x0F);
+-	} else
+-	{
+-		if (!(m_dwSongFlags & SONG_FIRSTTICK))
+-		{
+-			if (param & 0x0F) nChnSlide = -(int)(param & 0x0F);
+-			else nChnSlide = (int)((param & 0xF0) >> 4);
+-		}
+-	}
+-	if (nChnSlide)
+-	{
+-		nChnSlide += pChn->nGlobalVol;
+-		if (nChnSlide < 0) nChnSlide = 0;
+-		if (nChnSlide > 64) nChnSlide = 64;
+-		pChn->nGlobalVol = nChnSlide;
+-	}
+-}
+-
+-
+-void CSoundFile::ExtendedMODCommands(UINT nChn, UINT param)
+-//---------------------------------------------------------
+-{
+-	MODCHANNEL *pChn = &Chn[nChn];
+-	UINT command = param & 0xF0;
+-	param &= 0x0F;
+-	switch(command)
+-	{
+-	// E0x: Set Filter
+-	// E1x: Fine Portamento Up
+-	case 0x10:	if ((param) || (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))) FinePortamentoUp(pChn, param); break;
+-	// E2x: Fine Portamento Down
+-	case 0x20:	if ((param) || (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))) FinePortamentoDown(pChn, param); break;
+-	// E3x: Set Glissando Control
+-	case 0x30:	pChn->dwFlags &= ~CHN_GLISSANDO; if (param) pChn->dwFlags |= CHN_GLISSANDO; break;
+-	// E4x: Set Vibrato WaveForm
+-	case 0x40:	pChn->nVibratoType = param & 0x07; break;
+-	// E5x: Set FineTune
+-	case 0x50:	if (m_nTickCount) break;
+-				pChn->nC4Speed = S3MFineTuneTable[param];
+-				if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))
+-					pChn->nFineTune = param*2;
+-				else
+-					pChn->nFineTune = MOD2XMFineTune(param);
+-				if (pChn->nPeriod) pChn->nPeriod = GetPeriodFromNote(pChn->nNote, pChn->nFineTune, pChn->nC4Speed);
+-				break;
+-	// E6x: Pattern Loop
+-	// E7x: Set Tremolo WaveForm
+-	case 0x70:	pChn->nTremoloType = param & 0x07; break;
+-	// E8x: Set 4-bit Panning
+-	case 0x80:	if (!m_nTickCount) { pChn->nPan = (param << 4) + 8; pChn->dwFlags |= CHN_FASTVOLRAMP; } break;
+-	// E9x: Retrig
+-	case 0x90:	RetrigNote(nChn, param); break;
+-	// EAx: Fine Volume Up
+-	case 0xA0:	if ((param) || (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))) FineVolumeUp(pChn, param); break;
+-	// EBx: Fine Volume Down
+-	case 0xB0:	if ((param) || (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))) FineVolumeDown(pChn, param); break;
+-	// ECx: Note Cut
+-	case 0xC0:	NoteCut(nChn, param); break;
+-	// EDx: Note Delay
+-	// EEx: Pattern Delay
+-	// EFx: MOD: Invert Loop, XM: Set Active Midi Macro
+-	case 0xF0:	pChn->nActiveMacro = param;	break;
+-	}
+-}
+-
+-
+-void CSoundFile::ExtendedS3MCommands(UINT nChn, UINT param)
+-//---------------------------------------------------------
+-{
+-	MODCHANNEL *pChn = &Chn[nChn];
+-	UINT command = param & 0xF0;
+-	param &= 0x0F;
+-	switch(command)
+-	{
+-	// S0x: Set Filter
+-	// S1x: Set Glissando Control
+-	case 0x10:	pChn->dwFlags &= ~CHN_GLISSANDO; if (param) pChn->dwFlags |= CHN_GLISSANDO; break;
+-	// S2x: Set FineTune
+-	case 0x20:	if (m_nTickCount) break;
+-				pChn->nC4Speed = S3MFineTuneTable[param & 0x0F];
+-				pChn->nFineTune = MOD2XMFineTune(param);
+-				if (pChn->nPeriod) pChn->nPeriod = GetPeriodFromNote(pChn->nNote, pChn->nFineTune, pChn->nC4Speed);
+-				break;
+-	// S3x: Set Vibrato WaveForm
+-	case 0x30:	pChn->nVibratoType = param & 0x07; break;
+-	// S4x: Set Tremolo WaveForm
+-	case 0x40:	pChn->nTremoloType = param & 0x07; break;
+-	// S5x: Set Panbrello WaveForm
+-	case 0x50:	pChn->nPanbrelloType = param & 0x07; break;
+-	// S6x: Pattern Delay for x frames
+-	case 0x60:	m_nFrameDelay = param; break;
+-	// S7x: Envelope Control
+-	case 0x70:	if (m_nTickCount) break;
+-				switch(param)
+-				{
+-				case 0:
+-				case 1:
+-				case 2:
+-					{
+-						MODCHANNEL *bkp = &Chn[m_nChannels];
+-						for (UINT i=m_nChannels; i<MAX_CHANNELS; i++, bkp++)
+-						{
+-							if (bkp->nMasterChn == nChn+1)
+-							{
+-								if (param == 1) KeyOff(i); else
+-								if (param == 2) bkp->dwFlags |= CHN_NOTEFADE; else
+-									{ bkp->dwFlags |= CHN_NOTEFADE; bkp->nFadeOutVol = 0; }
+-							}
+-						}
+-					}
+-					break;
+-				case 3:		pChn->nNNA = NNA_NOTECUT; break;
+-				case 4:		pChn->nNNA = NNA_CONTINUE; break;
+-				case 5:		pChn->nNNA = NNA_NOTEOFF; break;
+-				case 6:		pChn->nNNA = NNA_NOTEFADE; break;
+-				case 7:		pChn->dwFlags &= ~CHN_VOLENV; break;
+-				case 8:		pChn->dwFlags |= CHN_VOLENV; break;
+-				case 9:		pChn->dwFlags &= ~CHN_PANENV; break;
+-				case 10:	pChn->dwFlags |= CHN_PANENV; break;
+-				case 11:	pChn->dwFlags &= ~CHN_PITCHENV; break;
+-				case 12:	pChn->dwFlags |= CHN_PITCHENV; break;
+-				}
+-				break;
+-	// S8x: Set 4-bit Panning
+-	case 0x80:
+-			pChn->dwFlags &= ~CHN_SURROUND;
+-			if (!m_nTickCount) {
+-				pChn->nPan = (param << 4) + 8;
+-				pChn->dwFlags |= CHN_FASTVOLRAMP;
+-			}
+-			break;
+-	// S9x: Set Surround
+-	case 0x90:	ExtendedChannelEffect(pChn, param & 0x0F); break;
+-	// SAx: Set 64k Offset
+-	case 0xA0:	if (!m_nTickCount)
+-				{
+-					if (m_nType & MOD_TYPE_S3M) {
+-						pChn->nPan = ((param ^ 8) << 4) + 8;
+-						pChn->dwFlags &= ~CHN_SURROUND;
+-						pChn->dwFlags |= CHN_FASTVOLRAMP;
+-					} else {
+-						pChn->nOldHiOffset = param;
+-						if ((pChn->nRowNote) && (pChn->nRowNote < 0x80))
+-						{
+-							DWORD pos = param << 16;
+-							if (pos < pChn->nLength) pChn->nPos = pos;
+-						}
+-					}
+-				}
+-				break;
+-	// SBx: Pattern Loop
+-	// SCx: Note Cut
+-	case 0xC0:	NoteCut(nChn, param); break;
+-	// SDx: Note Delay
+-	// case 0xD0:	break;
+-	// SEx: Pattern Delay for x rows
+-	// SFx: S3M: Funk Repeat, IT: Set Active Midi Macro
+-	case 0xF0:	pChn->nActiveMacro = param; break;
+-	}
+-}
+-
+-
+-void CSoundFile::ExtendedChannelEffect(MODCHANNEL *pChn, UINT param)
+-//------------------------------------------------------------------
+-{
+-	// S9x and X9x commands (S3M/XM/IT only)
+-	if (m_nTickCount) return;
+-	switch(param & 0x0F)
+-	{
+-        // S91: Surround On
+-	case 0x01:	pChn->dwFlags |= CHN_SURROUND; pChn->nPan = 128; break;
+-	////////////////////////////////////////////////////////////
+-	// Modplug Extensions
+-	// S90: Surround Off
+-	case 0x00:	pChn->dwFlags &= ~CHN_SURROUND;	break;
+-	// S98: Reverb Off
+-	case 0x08:
+-		pChn->dwFlags &= ~CHN_REVERB;
+-		pChn->dwFlags |= CHN_NOREVERB;
+-		break;
+-	// S99: Reverb On
+-	case 0x09:
+-		pChn->dwFlags &= ~CHN_NOREVERB;
+-		pChn->dwFlags |= CHN_REVERB;
+-		break;
+-	// S9A: 2-Channels surround mode
+-	case 0x0A:
+-		m_dwSongFlags &= ~SONG_SURROUNDPAN;
+-		break;
+-	// S9B: 4-Channels surround mode
+-	case 0x0B:
+-		m_dwSongFlags |= SONG_SURROUNDPAN;
+-		break;
+-	// S9C: IT Filter Mode
+-	case 0x0C:
+-		m_dwSongFlags &= ~SONG_MPTFILTERMODE;
+-		break;
+-	// S9D: MPT Filter Mode
+-	case 0x0D:
+-		m_dwSongFlags |= SONG_MPTFILTERMODE;
+-		break;
+-	// S9E: Go forward
+-	case 0x0E:
+-		pChn->dwFlags &= ~(CHN_PINGPONGFLAG);
+-		break;
+-	// S9F: Go backward (set position at the end for non-looping samples)
+-	case 0x0F:
+-		if ((!(pChn->dwFlags & CHN_LOOP)) && (!pChn->nPos) && (pChn->nLength))
+-		{
+-			pChn->nPos = pChn->nLength - 1;
+-			pChn->nPosLo = 0xFFFF;
+-		}
+-		pChn->dwFlags |= CHN_PINGPONGFLAG;
+-		break;
+-	}
+-}
+-
+-// this is all brisby
+-void CSoundFile::MidiSend(unsigned char *data, unsigned int len, UINT nChn, int fake)
+-{
+-	MODCHANNEL *pChn = &Chn[nChn];
+-	int oldcutoff;
+-
+-	if (len > 2 && data[0] == 0xF0 && data[1] == 0xF0) {
+-		/* impulse tracker filter control (mfg. 0xF0) */
+-		if (len == 5) {
+-			switch (data[2]) {
+-			case 0x00: /* set cutoff */
+-				oldcutoff = pChn->nCutOff;
+-				if (data[3] < 0x80) pChn->nCutOff = data[3];
+-#ifndef NO_FILTER
+-				oldcutoff -= pChn->nCutOff;
+-
+-				if (oldcutoff < 0) oldcutoff = -oldcutoff;
+-				if ((pChn->nVolume > 0) || (oldcutoff < 0x10)
+-				 || (!(pChn->dwFlags & CHN_FILTER))
+-				|| (!(pChn->nLeftVol|pChn->nRightVol)))
+-					SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER)
+-							? FALSE : TRUE);
+-#endif // NO_FILTER
+-				break;
+-			case 0x01: /* set resonance */
+-				if (data[3] < 0x80) pChn->nResonance = data[3];
+-#ifndef NO_FILTER
+-				SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? FALSE : TRUE);
+-#endif // NO_FILTER
+-				break;
+-			};
+-		}
+-	}
+-
+-	if (!fake && _midi_out_raw) {
+-		/* okay, this is kind of how it works.
+-		we pass m_nBufferCount as here because while
+-			1000 * ((8((buffer_size/2) - m_nBufferCount)) / sample_rate)
+-		is the number of msec we need to delay by, libmodplug simply doesn't know
+-		what the buffer size is at this point so m_nBufferCount simply has no
+-		frame of reference.
+-
+-		fortunately, schism does and can complete this (tags: _schism_midi_out_raw )
+-
+-		*/
+-		_midi_out_raw(data, len, m_nBufferCount);
+-	}
+-}
+-
+-static int _was_complete_midi(unsigned char *q, unsigned int len, int nextc)
+-{
+-	if (len == 0) return 0;
+-	if (*q == 0xF0) return (q[len-1] == 0xF7 ? 1 : 0);
+-	return ((nextc & 0x80) ? 1 : 0);
+-}
+-
+-void CSoundFile::ProcessMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param,
+-			UINT note, UINT velocity, UINT use_instr)
+-//---------------------------------------------------------------------------
+-{
+-/* this was all wrong. -mrsb */
+-	MODCHANNEL *pChn = &Chn[nChn];
+-	INSTRUMENTHEADER *penv = (m_dwSongFlags & SONG_INSTRUMENTMODE)
+-			? Headers[use_instr
+-					?use_instr
+-					:pChn->nLastInstr]
+-			: NULL;
+-	unsigned char outbuffer[64];
+-	unsigned char cx;
+-	int mc, fake = 0;
+-	int saw_c;
+-	int i, j, x;
+-
+-	saw_c = 0;
+-	if (!penv || penv->nMidiChannel == 0) {
+-		/* okay, there _IS_ no real midi channel. forget this for now... */
+-		mc = 15;
+-		fake = 1;
+-
+-	} else if (penv->nMidiChannel > 16) {
+-		mc = (nChn-1) % 16;
+-	} else {
+-		mc = (penv->nMidiChannel-1);
+-	}
+-
+-	for (i = j = x = 0, cx =0; i <= 32 && pszMidiMacro[i]; i++) {
+-		int c, cw;
+-		if (pszMidiMacro[i] >= '0' && pszMidiMacro[i] <= '9') {
+-			c = pszMidiMacro[i] - '0';
+-			cw = 1;
+-		} else if (pszMidiMacro[i] >= 'A' && pszMidiMacro[i] <= 'F') {
+-			c = (pszMidiMacro[i] - 'A') + 10;
+-			cw = 1;
+-		} else if (pszMidiMacro[i] == 'c') {
+-			c = mc;
+-			cw = 1;
+-			saw_c = 1;
+-		} else if (pszMidiMacro[i] == 'n') {
+-			c = (note-1);
+-			cw = 2;
+-		} else if (pszMidiMacro[i] == 'v') {
+-			c = velocity;
+-			cw = 2;
+-		} else if (pszMidiMacro[i] == 'u') {
+-			c = (pChn->nVolume >> 1);
+-			if (c > 127) c = 127;
+-			cw = 2;
+-		} else if (pszMidiMacro[i] == 'x') {
+-			c = pChn->nPan;
+-			if (c > 127) c = 127;
+-			cw = 2;
+-		} else if (pszMidiMacro[i] == 'y') {
+-			c = pChn->nRealPan;
+-			if (c > 127) c = 127;
+-			cw = 2;
+-		} else if (pszMidiMacro[i] == 'a') {
+-			if (!penv)
+-				c = 0;
+-			else
+-				c = (penv->wMidiBank >> 7) & 127;
+-			cw = 2;
+-		} else if (pszMidiMacro[i] == 'b') {
+-			if (!penv)
+-				c = 0;
+-			else
+-				c = penv->wMidiBank & 127;
+-			cw = 2;
+-		} else if (pszMidiMacro[i] == 'z' || pszMidiMacro[i] == 'p') {
+-			c = param & 0x7F;
+-			cw = 2;
+-		} else {
+-			continue;
+-		}
+-		if (j == 0 && cw == 1) {
+-			cx = c;
+-			j = 1;
+-			continue;
+-		} else if (j == 1 && cw == 1) {
+-			cx = (cx << 4) | c;
+-			j = 0;
+-		} else if (j == 0) {
+-			cx = c;
+-		} else if (j == 1) {
+-			outbuffer[x] = cx;
+-			x++;
+-
+-			cx = c;
+-			j = 0;
+-		}
+-		// start of midi message
+-		if (_was_complete_midi(outbuffer,x,cx)) {
+-			MidiSend(outbuffer, x, nChn,saw_c && fake);
+-			x = 0;
+-		}
+-		outbuffer[x] = cx;
+-		x++;
+-	}
+-	if (j == 1) {
+-		outbuffer[x] = cx;
+-		x++;
+-	}
+-	if (x) {
+-		// terminate sysex
+-		if (!_was_complete_midi(outbuffer,x,0xFF)) {
+-			if (*outbuffer == 0xF0) {
+-				outbuffer[x] = 0xF7;
+-				x++;
+-			}
+-		}
+-		MidiSend(outbuffer, x, nChn,saw_c && fake);
+-	}
+-}
+-
+-
+-void CSoundFile::RetrigNote(UINT nChn, UINT param)
+-//------------------------------------------------
+-{
+-	// Retrig: bit 8 is set if it's the new XM retrig
+-	MODCHANNEL *pChn = &Chn[nChn];
+-	UINT nRetrigSpeed = param & 0x0F;
+-	UINT nRetrigCount = pChn->nRetrigCount;
+-	BOOL bDoRetrig = FALSE;
+-
+-	if (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT))
+-	{
+-		if (!nRetrigSpeed) nRetrigSpeed = 1;
+-		if (m_nMusicSpeed < nRetrigSpeed) {
+-			if (nRetrigCount >= nRetrigSpeed) {
+-				bDoRetrig = TRUE;
+-				nRetrigCount = 0;
+-			} else {
+-				nRetrigCount++;
+-			}
+-		} else {
+-			if ((nRetrigCount) && (!(nRetrigCount % nRetrigSpeed))) bDoRetrig = TRUE;
+-			nRetrigCount++;
+-		}
+-	} else {
+-		UINT realspeed = nRetrigSpeed;
+-		if ((param & 0x100) && (pChn->nRowVolCmd == VOLCMD_VOLUME) && (pChn->nRowParam & 0xF0)) realspeed++;
+-		if ((m_nTickCount) || (param & 0x100))
+-		{
+-			if (!realspeed) realspeed = 1;
+-			if ((!(param & 0x100)) && (m_nMusicSpeed) && (!(m_nTickCount % realspeed))) bDoRetrig = TRUE;
+-			nRetrigCount++;
+-		} else if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) nRetrigCount = 0;
+-		if (nRetrigCount >= realspeed)
+-		{
+-			if ((m_nTickCount) || ((param & 0x100) && (!pChn->nRowNote))) bDoRetrig = TRUE;
+-		}
+-	}
+-	if (bDoRetrig)
+-	{
+-		UINT dv = (param >> 4) & 0x0F;
+-		if (dv)
+-		{
+-			int vol = pChn->nVolume;
+-			if (retrigTable1[dv])
+-				vol = (vol * retrigTable1[dv]) >> 4;
+-			else
+-				vol += ((int)retrigTable2[dv]) << 2;
+-			if (vol < 0) vol = 0;
+-			if (vol > 256) vol = 256;
+-			pChn->nVolume = vol;
+-			pChn->dwFlags |= CHN_FASTVOLRAMP;
+-		}
+-		UINT nNote = pChn->nNewNote;
+-		LONG nOldPeriod = pChn->nPeriod;
+-		if ((nNote) && (nNote <= 120) && (pChn->nLength)) CheckNNA(nChn, 0, nNote, TRUE);
+-		BOOL bResetEnv = FALSE;
+-		if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))
+-		{
+-			if ((pChn->nRowInstr) && (param < 0x100)) { InstrumentChange(pChn, pChn->nRowInstr, FALSE, FALSE); bResetEnv = TRUE; }
+-			if (param < 0x100) bResetEnv = TRUE;
+-		}
+-		NoteChange(nChn, nNote, FALSE, bResetEnv);
+-		if ((m_nType & MOD_TYPE_IT) && (!pChn->nRowNote) && (nOldPeriod)) pChn->nPeriod = nOldPeriod;
+-		if (!(m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT))) nRetrigCount = 0;
+-	}
+-	pChn->nRetrigCount = (BYTE)nRetrigCount;
+-}
+-
+-
+-void CSoundFile::DoFreqSlide(MODCHANNEL *pChn, LONG nFreqSlide)
+-//-------------------------------------------------------------
+-{
+-	// IT Linear slides
+-	if (!pChn->nPeriod) return;
+-	if ((m_dwSongFlags & SONG_LINEARSLIDES) && (!(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))))
+-	{
+-		if (nFreqSlide < 0)
+-		{
+-			UINT n = (- nFreqSlide) >> 2;
+-			if (n > 255) n = 255;
+-			pChn->nPeriod = _muldivr(pChn->nPeriod, LinearSlideDownTable[n], 65536);
+-		} else
+-		{
+-			UINT n = (nFreqSlide) >> 2;
+-
+-			if (n > 255) n = 255;
+-			pChn->nPeriod = _muldivr(pChn->nPeriod, LinearSlideUpTable[n], 65536);
+-		}
+-	} else
+-	{
+-		pChn->nPeriod += nFreqSlide;
+-	}
+-	if (pChn->nPeriod < 1)
+-	{
+-		pChn->nPeriod = 1;
+-		if (m_nType & MOD_TYPE_IT)
+-		{
+-			pChn->dwFlags |= CHN_NOTEFADE;
+-			pChn->nFadeOutVol = 0;
+-		}
+-	}
+-}
+-
+-
+-void CSoundFile::NoteCut(UINT nChn, UINT nTick)
+-//---------------------------------------------
+-{
+-	if (m_nTickCount == nTick)
+-	{
+-		MODCHANNEL *pChn = &Chn[nChn];
+-		// if (m_dwSongFlags & SONG_INSTRUMENTMODE) KeyOff(pChn); ?
+-		pChn->nVolume = 0;
+-		pChn->dwFlags |= CHN_FASTVOLRAMP;
+-		pChn->nLength = 0;
+-	}
+-}
+-
+-
+-void CSoundFile::KeyOff(UINT nChn)
+-//--------------------------------
+-{
+-	MODCHANNEL *pChn = &Chn[nChn];
+-	BOOL bKeyOn = (pChn->dwFlags & CHN_KEYOFF) ? FALSE : TRUE;
+-	pChn->dwFlags |= CHN_KEYOFF;
+-	//if ((!pChn->pHeader) || (!(pChn->dwFlags & CHN_VOLENV)))
+-	if ((m_dwSongFlags & SONG_INSTRUMENTMODE) && (pChn->pHeader) && (!(pChn->dwFlags & CHN_VOLENV)))
+-	{
+-		pChn->dwFlags |= CHN_NOTEFADE;
+-	}
+-	if (!pChn->nLength) return;
+-	if ((pChn->dwFlags & CHN_SUSTAINLOOP) && (pChn->pInstrument) && (bKeyOn))
+-	{
+-		MODINSTRUMENT *psmp = pChn->pInstrument;
+-		if (psmp->uFlags & CHN_LOOP)
+-		{
+-			if (psmp->uFlags & CHN_PINGPONGLOOP)
+-				pChn->dwFlags |= CHN_PINGPONGLOOP;
+-			else
+-				pChn->dwFlags &= ~(CHN_PINGPONGLOOP|CHN_PINGPONGFLAG);
+-			pChn->dwFlags |= CHN_LOOP;
+-			pChn->nLength = psmp->nLength;
+-			pChn->nLoopStart = psmp->nLoopStart;
+-			pChn->nLoopEnd = psmp->nLoopEnd;
+-			if (pChn->nLength > pChn->nLoopEnd) pChn->nLength = pChn->nLoopEnd;
+-		} else
+-		{
+-			pChn->dwFlags &= ~(CHN_LOOP|CHN_PINGPONGLOOP|CHN_PINGPONGFLAG);
+-			pChn->nLength = psmp->nLength;
+-		}
+-	}
+-	if ((m_dwSongFlags & SONG_INSTRUMENTMODE) && pChn->pHeader)
+-	{
+-		INSTRUMENTHEADER *penv = pChn->pHeader;
+-		if (((penv->dwFlags & ENV_VOLLOOP) || (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))) && (penv->nFadeOut))
+-			pChn->dwFlags |= CHN_NOTEFADE;
+-	}
+-}
+-
+-
+-//////////////////////////////////////////////////////////
+-// CSoundFile: Global Effects
+-
+-
+-void CSoundFile::SetSpeed(UINT param)
+-//-----------------------------------
+-{
+-        if (param)
+-                m_nMusicSpeed = param;
+-}
+-
+-
+-void CSoundFile::SetTempo(UINT param)
+-//-----------------------------------
+-{
+-	if (param < 0x20)
+-	{
+-#if 0 // argh... this is completely wrong
+-		// Tempo Slide
+-		if ((param & 0xF0) == 0x10)
+-		{
+-			m_nMusicTempo += (param & 0x0F) * 2;
+-			if (m_nMusicTempo > 255) m_nMusicTempo = 255;
+-		} else
+-		{
+-			m_nMusicTempo -= (param & 0x0F) * 2;
+-			if ((LONG)m_nMusicTempo < 32) m_nMusicTempo = 32;
+-		}
+-#endif
+-	} else
+-	{
+-		m_nMusicTempo = param;
+-	}
+-}
+-
+-
+-int CSoundFile::PatternLoop(MODCHANNEL *pChn, UINT param)
+-//-------------------------------------------------------
+-{
+-	if (param)
+-	{
+-		if (pChn->nPatternLoopCount)
+-		{
+-			pChn->nPatternLoopCount--;
+-			if (!pChn->nPatternLoopCount) {
+-                                // this should get rid of that nasty infinite loop for cases like
+-                                //     ... .. .. SB0
+-                                //     ... .. .. SB1
+-                                //     ... .. .. SB1
+-                                // it still doesn't work right in a few strange cases, but oh well :P
+-                                pChn->nPatternLoop = m_nRow + 1;
+-                                return -1;
+-                        }
+-		} else
+-		{
+-                        // hmm. the pattern loop shouldn't care about
+-                        // other channels at all... i'm not really
+-                        // sure what this code is doing :/
+-#if 0
+-			MODCHANNEL *p = Chn;
+-			for (UINT i=0; i<m_nChannels; i++, p++) if (p != pChn)
+-			{
+-				// Loop already done
+-				if (p->nPatternLoopCount) return -1;
+-			}
+-#endif
+-			pChn->nPatternLoopCount = param;
+-		}
+-		return pChn->nPatternLoop;
+-	} else
+-	{
+-		pChn->nPatternLoop = m_nRow;
+-	}
+-	return -1;
+-}
+-
+-
+-void CSoundFile::GlobalVolSlide(UINT param)
+-//-----------------------------------------
+-{
+-	LONG nGlbSlide = 0;
+-	if (param) m_nOldGlbVolSlide = param; else param = m_nOldGlbVolSlide;
+-	if (((param & 0x0F) == 0x0F) && (param & 0xF0))
+-	{
+-		if (m_dwSongFlags & SONG_FIRSTTICK) nGlbSlide = (param >> 4) * 2;
+-	} else
+-	if (((param & 0xF0) == 0xF0) && (param & 0x0F))
+-	{
+-		if (m_dwSongFlags & SONG_FIRSTTICK) nGlbSlide = - (int)((param & 0x0F) * 2);
+-	} else
+-	{
+-		if (!(m_dwSongFlags & SONG_FIRSTTICK))
+-		{
+-			if (param & 0xF0) nGlbSlide = (int)((param & 0xF0) >> 4) * 2;
+-			else nGlbSlide = -(int)((param & 0x0F) * 2);
+-		}
+-	}
+-	if (nGlbSlide)
+-	{
+-		if (m_nType != MOD_TYPE_IT) nGlbSlide *= 2;
+-		nGlbSlide += m_nGlobalVolume;
+-		if (nGlbSlide < 0) nGlbSlide = 0;
+-		if (nGlbSlide > 256) nGlbSlide = 256;
+-		m_nGlobalVolume = nGlbSlide;
+-	}
+-}
+-
+-
+-DWORD CSoundFile::IsSongFinished(UINT nStartOrder, UINT nStartRow) const
+-//----------------------------------------------------------------------
+-{
+-	UINT nOrd;
+-
+-	for (nOrd=nStartOrder; nOrd<MAX_ORDERS; nOrd++)
+-	{
+-		UINT nPat = Order[nOrd];
+-		if (nPat != 0xFE)
+-		{
+-			MODCOMMAND *p;
+-
+-			if (nPat >= MAX_PATTERNS) break;
+-			p = Patterns[nPat];
+-			if (p)
+-			{
+-				UINT len = PatternSize[nPat] * m_nChannels;
+-				UINT pos = (nOrd == nStartOrder) ? nStartRow : 0;
+-				pos *= m_nChannels;
+-				while (pos < len)
+-				{
+-					UINT cmd;
+-					if ((p[pos].note) || (p[pos].volcmd)) return 0;
+-					cmd = p[pos].command;
+-					if (cmd == CMD_MODCMDEX)
+-					{
+-						UINT cmdex = p[pos].param & 0xF0;
+-						if ((!cmdex) || (cmdex == 0x60) || (cmdex == 0xE0) || (cmdex == 0xF0)) cmd = 0;
+-					}
+-					if ((cmd) && (cmd != CMD_SPEED) && (cmd != CMD_TEMPO)) return 0;
+-					pos++;
+-				}
+-			}
+-		}
+-	}
+-	return (nOrd < MAX_ORDERS) ? nOrd : MAX_ORDERS-1;
+-}
+-
+-
+-BOOL CSoundFile::IsValidBackwardJump(UINT nStartOrder, UINT nStartRow, UINT nJumpOrder, UINT nJumpRow) const
+-//----------------------------------------------------------------------------------------------------------
+-{
+-	while ((nJumpOrder < MAX_PATTERNS) && (Order[nJumpOrder] == 0xFE)) nJumpOrder++;
+-	if ((nStartOrder >= MAX_PATTERNS) || (nJumpOrder >= MAX_PATTERNS)) return FALSE;
+-	// Treat only case with jumps in the same pattern
+-	if (nJumpOrder > nStartOrder) return TRUE;
+-	if ((nJumpOrder < nStartOrder) || (nJumpRow >= PatternSize[nStartOrder])
+-	 || (!Patterns[nStartOrder]) || (nStartRow >= 256) || (nJumpRow >= 256)) return FALSE;
+-	// See if the pattern is being played backward
+-	BYTE row_hist[256];
+-	memset(row_hist, 0, sizeof(row_hist));
+-	UINT nRows = PatternSize[nStartOrder], row = nJumpRow;
+-	if (nRows > 256) nRows = 256;
+-	row_hist[nStartRow] = TRUE;
+-	while ((row < 256) && (!row_hist[row]))
+-	{
+-		if (row >= nRows) return TRUE;
+-		row_hist[row] = TRUE;
+-		MODCOMMAND *p = Patterns[nStartOrder] + row * m_nChannels;
+-		row++;
+-		int breakrow = -1, posjump = 0;
+-		for (UINT i=0; i<m_nChannels; i++, p++)
+-		{
+-			if (p->command == CMD_POSITIONJUMP)
+-			{
+-				if (p->param < nStartOrder) return FALSE;
+-				if (p->param > nStartOrder) return TRUE;
+-				posjump = TRUE;
+-			} else
+-			if (p->command == CMD_PATTERNBREAK)
+-			{
+-				breakrow = p->param;
+-			}
+-		}
+-		if (breakrow >= 0)
+-		{
+-			if (!posjump) return TRUE;
+-			row = breakrow;
+-		}
+-		if (row >= nRows) return TRUE;
+-	}
+-	return FALSE;
+-}
+-
+-
+-//////////////////////////////////////////////////////
+-// Note/Period/Frequency functions
+-
+-UINT CSoundFile::GetNoteFromPeriod(UINT period) const
+-//---------------------------------------------------
+-{
+-	if (!period) return 0;
+-	if (m_nType & (MOD_TYPE_MED|MOD_TYPE_MOD|MOD_TYPE_MTM|MOD_TYPE_669|MOD_TYPE_OKT|MOD_TYPE_AMF0))
+-	{
+-		period >>= 2;
+-		for (UINT i=0; i<6*12; i++)
+-		{
+-			if (period >= ProTrackerPeriodTable[i])
+-			{
+-				if ((period != ProTrackerPeriodTable[i]) && (i))
+-				{
+-					UINT p1 = ProTrackerPeriodTable[i-1];
+-					UINT p2 = ProTrackerPeriodTable[i];
+-					if (p1 - period < (period - p2)) return i+36;
+-				}
+-				return i+1+36;
+-			}
+-		}
+-		return 6*12+36;
+-	} else
+-	{
+-		for (UINT i=1; i<120; i++)
+-		{
+-			LONG n = GetPeriodFromNote(i, 0, 0);
+-			if ((n > 0) && (n <= (LONG)period)) return i;
+-		}
+-		return 120;
+-	}
+-}
+-
+-// this last param was nC4Speed
+-UINT CSoundFile::GetLinearPeriodFromNote(UINT note, int nFineTune, UINT) const
+-{
+-	if ((!note) || (note > 0xF0)) return 0;
+-	if (m_nType & (MOD_TYPE_IT|MOD_TYPE_S3M|MOD_TYPE_STM|MOD_TYPE_MDL|MOD_TYPE_ULT|MOD_TYPE_WAV
+-				|MOD_TYPE_FAR|MOD_TYPE_DMF|MOD_TYPE_PTM|MOD_TYPE_AMS|MOD_TYPE_DBM|MOD_TYPE_AMF|MOD_TYPE_PSM))
+-	{
+-		note--;
+-		return (FreqS3MTable[note % 12] << 5) >> (note / 12);
+-	} else
+-	if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))
+-	{
+-		if (note < 13) note = 13;
+-		note -= 13;
+-		LONG l = ((120 - note) << 6) - (nFineTune / 2);
+-		if (l < 1) l = 1;
+-		return (UINT)l;
+-	} else
+-	{
+-		note--;
+-		nFineTune = XM2MODFineTune(nFineTune);
+-		if ((nFineTune) || (note < 36) || (note >= 36+6*12))
+-			return (ProTrackerTunedPeriods[nFineTune*12 + note % 12] << 5) >> (note / 12);
+-		else
+-			return (ProTrackerPeriodTable[note-36] << 2);
+-	}
+-}
+-
+-
+-UINT CSoundFile::GetPeriodFromNote(UINT note, int nFineTune, UINT nC4Speed) const
+-//-------------------------------------------------------------------------------
+-{
+-	if ((!note) || (note > 0xF0)) return 0;
+-	if (m_nType & (MOD_TYPE_IT|MOD_TYPE_S3M|MOD_TYPE_STM|MOD_TYPE_MDL|MOD_TYPE_ULT|MOD_TYPE_WAV
+-				|MOD_TYPE_FAR|MOD_TYPE_DMF|MOD_TYPE_PTM|MOD_TYPE_AMS|MOD_TYPE_DBM|MOD_TYPE_AMF|MOD_TYPE_PSM))
+-	{
+-		note--;
+-		if (m_dwSongFlags & SONG_LINEARSLIDES)
+-		{
+-			return (FreqS3MTable[note % 12] << 5) >> (note / 12);
+-		} else
+-		{
+-			if (!nC4Speed) nC4Speed = 8363;
+-			return _muldiv(8363, (FreqS3MTable[note % 12] << 5), nC4Speed << (note / 12));
+-		}
+-	} else
+-	if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))
+-	{
+-		if (note < 13) note = 13;
+-		note -= 13;
+-		if (m_dwSongFlags & SONG_LINEARSLIDES)
+-		{
+-			LONG l = ((120 - note) << 6) - (nFineTune / 2);
+-			if (l < 1) l = 1;
+-			return (UINT)l;
+-		} else
+-		{
+-			int finetune = nFineTune;
+-			UINT rnote = (note % 12) << 3;
+-			UINT roct = note / 12;
+-			int rfine = finetune / 16;
+-			int i = rnote + rfine + 8;
+-			if (i < 0) i = 0;
+-			if (i >= 104) i = 103;
+-			UINT per1 = XMPeriodTable[i];
+-			if ( finetune < 0 )
+-			{
+-				rfine--;
+-				finetune = -finetune;
+-			} else rfine++;
+-			i = rnote+rfine+8;
+-			if (i < 0) i = 0;
+-			if (i >= 104) i = 103;
+-			UINT per2 = XMPeriodTable[i];
+-			rfine = finetune & 0x0F;
+-			per1 *= 16-rfine;
+-			per2 *= rfine;
+-			return ((per1 + per2) << 1) >> roct;
+-		}
+-	} else
+-	{
+-		note--;
+-		nFineTune = XM2MODFineTune(nFineTune);
+-		if ((nFineTune) || (note < 36) || (note >= 36+6*12))
+-			return (ProTrackerTunedPeriods[nFineTune*12 + note % 12] << 5) >> (note / 12);
+-		else
+-			return (ProTrackerPeriodTable[note-36] << 2);
+-	}
+-}
+-
+-
+-UINT CSoundFile::GetFreqFromPeriod(UINT period, UINT nC4Speed, int nPeriodFrac) const
+-//-----------------------------------------------------------------------------------
+-{
+-	if (!period) return 0;
+-	if (m_nType & (MOD_TYPE_MED|MOD_TYPE_MOD|MOD_TYPE_MTM|MOD_TYPE_669|MOD_TYPE_OKT|MOD_TYPE_AMF0))
+-	{
+-		return (3546895L*4) / period;
+-	} else
+-	if (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2))
+-	{
+-		if (m_dwSongFlags & SONG_LINEARSLIDES)
+-			return XMLinearTable[period % 768] >> (period / 768);
+-		else
+-			return 8363 * 1712L / period;
+-	} else
+-	{
+-		if (m_dwSongFlags & SONG_LINEARSLIDES)
+-		{
+-			if (!nC4Speed) nC4Speed = 8363;
+-			return _muldiv(nC4Speed, 1712L << 8, (period << 8)+nPeriodFrac);
+-		} else
+-		{
+-			return _muldiv(8363, 1712L << 8, (period << 8)+nPeriodFrac);
+-		}
+-	}
+-}
+-
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/sndmix.cxx audacious-plugins-2.5.4/src/modplug/sndmix.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/sndmix.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/sndmix.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,1246 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+-*/
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-
+-// Volume ramp length, in 1/10 ms
+-#define VOLUMERAMPLEN	146	// 1.46ms = 64 samples at 44.1kHz
+-
+-// VU-Meter
+-#define VUMETER_DECAY		16
+-
+-// SNDMIX: These are global flags for playback control
+-LONG CSoundFile::m_nStreamVolume = 0x8000;
+-UINT CSoundFile::m_nMaxMixChannels = 256;
+-// Mixing Configuration (SetWaveConfig)
+-DWORD CSoundFile::gdwSysInfo = 0;
+-DWORD CSoundFile::gnChannels = 1;
+-DWORD CSoundFile::gdwSoundSetup = SNDMIX_NOBACKWARDJUMPS; // Do not allow song to loop infinitely
+-DWORD CSoundFile::gdwMixingFreq = 44100;
+-DWORD CSoundFile::gnBitsPerSample = 16;
+-// Mixing data initialized in
+-UINT CSoundFile::gnAGC = AGC_UNITY;
+-UINT CSoundFile::gnVolumeRampSamples = 64;
+-UINT CSoundFile::gnVULeft = 0;
+-UINT CSoundFile::gnVURight = 0;
+-UINT CSoundFile::gnCPUUsage = 0;
+-LPSNDMIXHOOKPROC CSoundFile::gpSndMixHook = NULL;
+-PMIXPLUGINCREATEPROC CSoundFile::gpMixPluginCreateProc = NULL;
+-LONG gnDryROfsVol = 0;
+-LONG gnDryLOfsVol = 0;
+-LONG gnRvbROfsVol = 0;
+-LONG gnRvbLOfsVol = 0;
+-int gbInitPlugins = 0;
+-
+-typedef DWORD (MPPASMCALL * LPCONVERTPROC)(LPVOID, int *, DWORD, LPLONG, LPLONG);
+-
+-extern DWORD MPPASMCALL Convert32To8(LPVOID lpBuffer, int *, DWORD nSamples, LONG mins[2], LONG maxs[2]);
+-extern DWORD MPPASMCALL Convert32To16(LPVOID lpBuffer, int *, DWORD nSamples, LONG mins[2], LONG maxs[2]);
+-extern DWORD MPPASMCALL Convert32To24(LPVOID lpBuffer, int *, DWORD nSamples, LONG mins[2], LONG maxs[2]);
+-extern DWORD MPPASMCALL Convert32To32(LPVOID lpBuffer, int *, DWORD nSamples, LONG mins[2], LONG maxs[2]);
+-extern UINT MPPASMCALL AGC(int *pBuffer, UINT nSamples, UINT nAGC);
+-extern VOID MPPASMCALL Dither(int *pBuffer, UINT nSamples, UINT nBits);
+-extern VOID MPPASMCALL InterleaveFrontRear(int *pFrontBuf, int *pRearBuf, DWORD nSamples);
+-extern VOID MPPASMCALL StereoFill(int *pBuffer, UINT nSamples, LPLONG lpROfs, LPLONG lpLOfs);
+-extern VOID MPPASMCALL MonoFromStereo(int *pMixBuf, UINT nSamples);
+-
+-extern short int ModSinusTable[64];
+-extern short int ModRampDownTable[64];
+-extern short int ModSquareTable[64];
+-extern short int ModRandomTable[64];
+-extern DWORD LinearSlideUpTable[256];
+-extern DWORD LinearSlideDownTable[256];
+-extern DWORD FineLinearSlideUpTable[16];
+-extern DWORD FineLinearSlideDownTable[16];
+-extern signed char ft2VibratoTable[256];	// -64 .. +64
+-extern int MixSoundBuffer[MIXBUFFERSIZE*4];
+-extern int MixRearBuffer[MIXBUFFERSIZE*2];
+-UINT gnReverbSend;
+-
+-
+-// Log tables for pre-amp
+-// We don't want the tracker to get too loud
+-const UINT PreAmpTable[16] =
+-{
+-	0x60, 0x60, 0x60, 0x70,	// 0-7
+-	0x80, 0x88, 0x90, 0x98,	// 8-15
+-	0xA0, 0xA4, 0xA8, 0xB0,	// 16-23
+-	0xB4, 0xB8, 0xBC, 0xC0,	// 24-31
+-};
+-
+-const UINT PreAmpAGCTable[16] =
+-{
+-	0x60, 0x60, 0x60, 0x60,
+-	0x68, 0x70, 0x78, 0x80,
+-	0x84, 0x88, 0x8C, 0x90,
+-	0x94, 0x98, 0x9C, 0xA0,
+-};
+-
+-
+-BOOL CSoundFile::InitPlayer(BOOL bReset)
+-//--------------------------------------
+-{
+-	if (m_nMaxMixChannels > MAX_CHANNELS) m_nMaxMixChannels = MAX_CHANNELS;
+-	if (gdwMixingFreq < 4000) gdwMixingFreq = 4000;
+-	if (gdwMixingFreq > MAX_SAMPLE_RATE) gdwMixingFreq = MAX_SAMPLE_RATE;
+-	gnVolumeRampSamples = (gdwMixingFreq * VOLUMERAMPLEN) / 100000;
+-	if (gnVolumeRampSamples < 8) gnVolumeRampSamples = 8;
+-	gnDryROfsVol = gnDryLOfsVol = 0;
+-	gnRvbROfsVol = gnRvbLOfsVol = 0;
+-	if (bReset)
+-	{
+-		gnVULeft = 0;
+-		gnVURight = 0;
+-		gnCPUUsage = 0;
+-	}
+-	gbInitPlugins = (bReset) ? 3 : 1;
+-	InitializeDSP(bReset);
+-	InitializeEQ(bReset);
+-	return TRUE;
+-}
+-
+-
+-BOOL CSoundFile::FadeSong(UINT msec)
+-//----------------------------------
+-{
+-	LONG nsamples = _muldiv(msec, gdwMixingFreq, 1000);
+-	if (nsamples <= 0) return FALSE;
+-	if (nsamples > 0x100000) nsamples = 0x100000;
+-	m_nBufferCount = nsamples;
+-	LONG nRampLength = m_nBufferCount;
+-	// Ramp everything down
+-	for (UINT noff=0; noff < m_nMixChannels; noff++)
+-	{
+-		MODCHANNEL *pramp = &Chn[ChnMix[noff]];
+-		if (!pramp) continue;
+-		pramp->nNewLeftVol = pramp->nNewRightVol = 0;
+-		pramp->nRightRamp = (-pramp->nRightVol << VOLUMERAMPPRECISION) / nRampLength;
+-		pramp->nLeftRamp = (-pramp->nLeftVol << VOLUMERAMPPRECISION) / nRampLength;
+-		pramp->nRampRightVol = pramp->nRightVol << VOLUMERAMPPRECISION;
+-		pramp->nRampLeftVol = pramp->nLeftVol << VOLUMERAMPPRECISION;
+-		pramp->nRampLength = nRampLength;
+-		pramp->dwFlags |= CHN_VOLUMERAMP;
+-	}
+-	m_dwSongFlags |= SONG_FADINGSONG;
+-	return TRUE;
+-}
+-
+-
+-BOOL CSoundFile::GlobalFadeSong(UINT msec)
+-//----------------------------------------
+-{
+-	if (m_dwSongFlags & SONG_GLOBALFADE) return FALSE;
+-	m_nGlobalFadeMaxSamples = _muldiv(msec, gdwMixingFreq, 1000);
+-	m_nGlobalFadeSamples = m_nGlobalFadeMaxSamples;
+-	m_dwSongFlags |= SONG_GLOBALFADE;
+-	return TRUE;
+-}
+-
+-
+-UINT CSoundFile::Read(LPVOID lpDestBuffer, UINT cbBuffer)
+-//-------------------------------------------------------
+-{
+-	LPBYTE lpBuffer = (LPBYTE)lpDestBuffer;
+-	LPCONVERTPROC pCvt = Convert32To8;
+-	LONG vu_min[2];
+-	LONG vu_max[2];
+-	UINT lRead, lMax, lSampleSize, lCount, lSampleCount, nStat=0;
+-#if 0
+-	UINT nMaxPlugins;
+-#endif
+-
+-	vu_min[0] = vu_min[1] = 0x7FFFFFFF;
+-	vu_max[0] = vu_max[1] = -0x7FFFFFFF;
+-
+-#if 0
+-	{
+-		nMaxPlugins = MAX_MIXPLUGINS;
+-		while ((nMaxPlugins > 0) && (!m_MixPlugins[nMaxPlugins-1].pMixPlugin)) nMaxPlugins--;
+-	}
+-#endif
+-	m_nMixStat = 0;
+-	lSampleSize = gnChannels;
+-	if (gnBitsPerSample == 16) { lSampleSize *= 2; pCvt = Convert32To16; }
+-	else if (gnBitsPerSample == 24) { lSampleSize *= 3; pCvt = Convert32To24; }
+-	else if (gnBitsPerSample == 32) { lSampleSize *= 4; pCvt = Convert32To32; }
+-	lMax = cbBuffer / lSampleSize;
+-	if ((!lMax) || (!lpBuffer) || (!m_nChannels)) return 0;
+-	lRead = lMax;
+-	if (m_dwSongFlags & SONG_ENDREACHED) goto MixDone;
+-	while (lRead > 0)
+-	{
+-		// Update Channel Data
+-		UINT lTotalSampleCount;
+-		if (!m_nBufferCount)
+-		{
+-			if (!(gdwSoundSetup & SNDMIX_DIRECTTODISK))
+-				m_nBufferCount = lRead;
+-			if (!ReadNote()) {
+-				m_dwSongFlags |= SONG_ENDREACHED;
+-				if (lRead == lMax) goto MixDone;
+-				if (!(gdwSoundSetup & SNDMIX_DIRECTTODISK))
+-					m_nBufferCount = lRead;
+-			}
+-			if (!m_nBufferCount) goto MixDone;
+-		}
+-		lCount = m_nBufferCount;
+-		if (lCount > MIXBUFFERSIZE) lCount = MIXBUFFERSIZE;
+-		if (lCount > lRead) lCount = lRead;
+-		if (!lCount) break;
+-		lSampleCount = lCount;
+-#ifndef MODPLUG_NO_REVERB
+-		gnReverbSend = 0;
+-#endif
+-
+-		// Resetting sound buffer
+-		StereoFill(MixSoundBuffer, lSampleCount, &gnDryROfsVol, &gnDryLOfsVol);
+-		if (gnChannels >= 2)
+-		{
+-			lSampleCount *= 2;
+-			m_nMixStat += CreateStereoMix(lCount);
+-#if 0
+-			if (nMaxPlugins) ProcessPlugins(lCount);
+-#endif
+-			ProcessStereoDSP(lCount);
+-		} else
+-		{
+-			m_nMixStat += CreateStereoMix(lCount);
+-#if 0
+-			if (nMaxPlugins) ProcessPlugins(lCount);
+-#endif
+-			MonoFromStereo(MixSoundBuffer, lCount);
+-			ProcessMonoDSP(lCount);
+-		}
+-
+-		if (gdwSoundSetup & SNDMIX_EQ)
+-		{
+-			if (gnChannels >= 2)
+-				EQStereo(MixSoundBuffer, lCount);
+-			else
+-				EQMono(MixSoundBuffer, lCount);
+-		}
+-
+-
+-		nStat++;
+-#ifndef NO_AGC
+-		// Automatic Gain Control
+-		if (gdwSoundSetup & SNDMIX_AGC) ProcessAGC(lSampleCount);
+-#endif
+-		lTotalSampleCount = lSampleCount;
+-		// Multichannel
+-		if (gnChannels > 2)
+-		{
+-			InterleaveFrontRear(MixSoundBuffer, MixRearBuffer, lSampleCount);
+-			lTotalSampleCount *= 2;
+-		}
+-		// Hook Function
+-		if (gpSndMixHook)
+-		{
+-			gpSndMixHook(MixSoundBuffer, lTotalSampleCount, gnChannels);
+-		}
+-		// Perform clipping + VU-Meter
+-		lpBuffer += pCvt(lpBuffer, MixSoundBuffer, lTotalSampleCount, vu_min, vu_max);
+-		// Buffer ready
+-		lRead -= lCount;
+-		m_nBufferCount -= lCount;
+-	}
+-MixDone:
+-	if (lRead) memset(lpBuffer, (gnBitsPerSample == 8) ? 0x80 : 0, lRead * lSampleSize);
+-	// VU-Meter
+-	vu_min[0] >>= 18;
+-	vu_min[1] >>= 18;
+-	vu_max[0] >>= 18;
+-	vu_max[1] >>= 18;
+-	if (vu_max[0] < vu_min[0]) vu_max[0] = vu_min[0];
+-	if (vu_max[1] < vu_min[1]) vu_max[1] = vu_min[1];
+-	if ((gnVULeft = (UINT)(vu_max[0] - vu_min[0])) > 0xFF)
+-		gnVULeft = 0xFF;
+-	if ((gnVURight = (UINT)(vu_max[1] - vu_min[1])) > 0xFF)
+-		gnVURight = 0xFF;
+-	if (nStat) { m_nMixStat += nStat-1; m_nMixStat /= nStat; }
+-	return lMax - lRead;
+-}
+-
+-
+-
+-/////////////////////////////////////////////////////////////////////////////
+-// Handles navigation/effects
+-
+-BOOL CSoundFile::ProcessRow()
+-//---------------------------
+-{
+-	if (++m_nTickCount >= m_nMusicSpeed * (m_nPatternDelay+1) + m_nFrameDelay)
+-	{
+-		m_nPatternDelay = 0;
+-		m_nFrameDelay = 0;
+-		m_nTickCount = 0;
+-		m_nRow = m_nNextRow;
+-		// Reset Pattern Loop Effect
+-		if (m_nCurrentPattern != m_nNextPattern) m_nCurrentPattern = m_nNextPattern;
+-		// Check if pattern is valid
+-		if (!(m_dwSongFlags & SONG_PATTERNLOOP))
+-		{
+-			m_nPattern = (m_nCurrentPattern < MAX_ORDERS) ? Order[m_nCurrentPattern] : 0xFF;
+-			if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) m_nPattern = 0xFE;
+-			while (m_nPattern >= MAX_PATTERNS)
+-			{
+-				// End of song ?
+-				if ((m_nPattern == 0xFF) || (m_nCurrentPattern >= MAX_ORDERS))
+-				{
+-					//if (!m_nRepeatCount)
+-						return FALSE;     //never repeat entire song
+-					if (!m_nRestartPos)
+-					{
+-						m_nMusicSpeed = m_nDefaultSpeed;
+-						m_nMusicTempo = m_nDefaultTempo;
+-						m_nGlobalVolume = m_nDefaultGlobalVolume;
+-						for (UINT i=0; i<MAX_CHANNELS; i++)
+-						{
+-							Chn[i].dwFlags |= CHN_NOTEFADE | CHN_KEYOFF;
+-							Chn[i].nFadeOutVol = 0;
+-							if (i < m_nChannels)
+-							{
+-								Chn[i].nGlobalVol = ChnSettings[i].nVolume;
+-								Chn[i].nVolume = ChnSettings[i].nVolume;
+-								Chn[i].nPan = ChnSettings[i].nPan;
+-								Chn[i].nPanSwing = Chn[i].nVolSwing = 0;
+-								Chn[i].nOldVolParam = 0;
+-								Chn[i].nOldOffset = 0;
+-								Chn[i].nOldHiOffset = 0;
+-								Chn[i].nPortamentoDest = 0;
+-								if (!Chn[i].nLength)
+-								{
+-									Chn[i].dwFlags = ChnSettings[i].dwFlags;
+-									Chn[i].nLoopStart = 0;
+-									Chn[i].nLoopEnd = 0;
+-									Chn[i].pHeader = NULL;
+-									Chn[i].pSample = NULL;
+-									Chn[i].pInstrument = NULL;
+-								}
+-							}
+-						}
+-					}
+-//					if (m_nRepeatCount > 0) m_nRepeatCount--;
+-					m_nCurrentPattern = m_nRestartPos;
+-					m_nRow = 0;
+-					if ((Order[m_nCurrentPattern] >= MAX_PATTERNS) || (!Patterns[Order[m_nCurrentPattern]])) return FALSE;
+-				} else
+-				{
+-					m_nCurrentPattern++;
+-				}
+-				m_nPattern = (m_nCurrentPattern < MAX_ORDERS) ? Order[m_nCurrentPattern] : 0xFF;
+-				if ((m_nPattern < MAX_PATTERNS) && (!Patterns[m_nPattern])) m_nPattern = 0xFE;
+-			}
+-			m_nNextPattern = m_nCurrentPattern;
+-		}
+-		// Weird stuff?
+-		if ((m_nPattern >= MAX_PATTERNS) || (!Patterns[m_nPattern])) return FALSE;
+-		// Should never happen
+-		if (m_nRow >= PatternSize[m_nPattern]) m_nRow = 0;
+-		m_nNextRow = m_nRow + 1;
+-		if (m_nNextRow >= PatternSize[m_nPattern])
+-		{
+-			if (!(m_dwSongFlags & SONG_PATTERNLOOP)) m_nNextPattern = m_nCurrentPattern + 1;
+-			m_nNextRow = 0;
+-		}
+-		// Reset channel values
+-		MODCHANNEL *pChn = Chn;
+-		MODCOMMAND *m = Patterns[m_nPattern] + m_nRow * m_nChannels;
+-		for (UINT nChn=0; nChn<m_nChannels; pChn++, nChn++, m++)
+-		{
+-			pChn->nRowNote = m->note;
+-			pChn->nRowInstr = m->instr;
+-			pChn->nRowVolCmd = m->volcmd;
+-			pChn->nRowVolume = m->vol;
+-			pChn->nRowCommand = m->command;
+-			pChn->nRowParam = m->param;
+-
+-			pChn->nLeftVol = pChn->nNewLeftVol;
+-			pChn->nRightVol = pChn->nNewRightVol;
+-			pChn->dwFlags &= ~(CHN_PORTAMENTO | CHN_VIBRATO | CHN_TREMOLO | CHN_PANBRELLO);
+-			pChn->nCommand = 0;
+-		}
+-	}
+-	// Should we process tick0 effects?
+-	if (!m_nMusicSpeed) m_nMusicSpeed = 1;
+-	m_dwSongFlags |= SONG_FIRSTTICK;
+-	if (m_nTickCount)
+-	{
+-		m_dwSongFlags &= ~SONG_FIRSTTICK;
+-		if ((!(m_nType & MOD_TYPE_XM)) && (m_nTickCount < m_nMusicSpeed * (1 + m_nPatternDelay)))
+-		{
+-			if (!(m_nTickCount % m_nMusicSpeed)) m_dwSongFlags |= SONG_FIRSTTICK;
+-		}
+-
+-	}
+-	// Update Effects
+-	return ProcessEffects();
+-}
+-
+-
+-////////////////////////////////////////////////////////////////////////////////////////////
+-// Handles envelopes & mixer setup
+-
+-BOOL CSoundFile::ReadNote()
+-//-------------------------
+-{
+-	// Checking end of row ?
+-	if (m_dwSongFlags & SONG_PAUSED)
+-	{
+-		/*m_nTickCount = 0;*/
+-		if (!m_nMusicSpeed) m_nMusicSpeed = 6;
+-		if (!m_nMusicTempo) m_nMusicTempo = 125;
+-		m_nPatternDelay = 0;
+-		m_nFrameDelay = 0;
+-
+-		m_dwSongFlags |= SONG_FIRSTTICK;
+-		if (m_nTickCount) {
+-			m_dwSongFlags &= ~SONG_FIRSTTICK;
+-		}
+-
+-		ProcessEffects();
+-		m_nTickCount++;
+-		if (m_nTickCount >= m_nMusicSpeed) {
+-			m_nTickCount = 0;
+-		}
+-		if (!ProcessEffects()) return FALSE;
+-	} else
+-	{
+-		if (!ProcessRow()) return FALSE;
+-	}
+-
+-	{ /* handle realtime closures */
+-		MODCHANNEL *pChn = Chn;
+-		for (UINT nChn=0; nChn<m_nChannels; pChn++, nChn++) {
+-			/* reset end of "row" */
+-			if (pChn->nRealtime && pChn->nRowNote && (pChn->nTickStart % m_nMusicSpeed) == (m_nTickCount % m_nMusicSpeed)) {
+-				pChn->nRealtime = 0;
+-				pChn->nRowNote = 0;
+-				pChn->nRowInstr = 0;
+-				//pChn->nMaster
+-				pChn->nRowVolCmd = 0;
+-				pChn->nRowVolume = 0;
+-				pChn->nRowCommand = 0;
+-				pChn->nRowParam = 0;
+-				pChn->nTickStart = 0;
+-			}
+-		}
+-	};
+-
+-	////////////////////////////////////////////////////////////////////////////////////
+-	m_nTotalCount++;
+-	if (!m_nMusicTempo) return FALSE;
+-	m_nBufferCount = (gdwMixingFreq * 5 * m_nTempoFactor) / (m_nMusicTempo << 8);
+-#ifdef MODPLUG_TRACKER
+-	if (m_dwSongFlags & SONG_PAUSED)
+-	{
+-		m_nBufferCount = gdwMixingFreq / 64; // 1/64 seconds
+-	}
+-#endif
+-
+-	// Master Volume + Pre-Amplification / Attenuation setup
+-	DWORD nMasterVol;
+-	{
+-		int nchn32 = 0;
+-		MODCHANNEL *pChn = Chn;	
+-		for (UINT nChn=0; nChn<m_nChannels; nChn++, pChn++) {
+-			nchn32++;
+-		}
+-		if (nchn32 < 1) nchn32 = 1;
+-		if (nchn32 > 31) nchn32 = 31;
+-
+-		int realmastervol = m_nMasterVolume;
+-		if (realmastervol > 0x80)
+-		{
+-			realmastervol = 0x80 + ((realmastervol - 0x80) * (nchn32+4)) / 16;
+-		}
+-
+-		DWORD mastervol = (realmastervol * (m_nSongPreAmp)) >> 6;
+-//		if (mastervol > 0x200) mastervol = 0x200;
+-		if ((m_dwSongFlags & SONG_GLOBALFADE) && (m_nGlobalFadeMaxSamples))
+-		{
+-			mastervol = _muldiv(mastervol, m_nGlobalFadeSamples, m_nGlobalFadeMaxSamples);
+-		}
+-
+-		UINT attenuation = (gdwSoundSetup & SNDMIX_AGC) ? PreAmpAGCTable[nchn32>>1] : PreAmpTable[nchn32>>1];
+-		if (attenuation < 1) attenuation = 1;
+-
+-		nMasterVol = (mastervol << 7) / attenuation;
+-		if (nMasterVol > 0x180) nMasterVol = 0x180;
+-	}
+-	////////////////////////////////////////////////////////////////////////////////////
+-	// Update channels data
+-	if (CSoundFile::gdwSoundSetup & SNDMIX_NOMIXING) return TRUE;
+-	m_nMixChannels = 0;
+-	MODCHANNEL *pChn = Chn;
+-	for (UINT nChn=0; nChn<MAX_CHANNELS; nChn++,pChn++)
+-	{
+-		if ((pChn->dwFlags & CHN_NOTEFADE) && (!(pChn->nFadeOutVol|pChn->nRightVol|pChn->nLeftVol)))
+-		{
+-			pChn->nLength = 0;
+-			pChn->nROfs = pChn->nLOfs = 0;
+-		}
+-		// Check for unused channel
+-		if ((nChn >= m_nChannels) && (!pChn->nLength))
+-		{
+-			pChn->nLeftVU = pChn->nRightVU = 0;
+-			continue;
+-		}
+-		// Reset channel data
+-		pChn->nInc = 0;
+-		pChn->nRealVolume = 0;
+-		pChn->nRealPan = pChn->nPan + pChn->nPanSwing;
+-		if (pChn->nRealPan < 0) pChn->nRealPan = 0;
+-		if (pChn->nRealPan > 256) pChn->nRealPan = 256;
+-		pChn->nRampLength = 0;
+-		// Calc Frequency
+-		if ((pChn->nPeriod)	&& (pChn->nLength))
+-		{
+-			int vol = pChn->nVolume + pChn->nVolSwing;
+-
+-			if (vol < 0) vol = 0;
+-			if (vol > 256) vol = 256;
+-			// Tremolo
+-			if (pChn->dwFlags & CHN_TREMOLO)
+-			{
+-				UINT trempos = pChn->nTremoloPos & 0x3F;
+-				if (vol > 0)
+-				{
+-					int tremattn = (m_nType & MOD_TYPE_XM) ? 5 : 6;
+-					switch (pChn->nTremoloType & 0x03)
+-					{
+-					case 1:
+-						vol += (ModRampDownTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
+-						break;
+-					case 2:
+-						vol += (ModSquareTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
+-						break;
+-					case 3:
+-						vol += (ModRandomTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
+-						break;
+-					default:
+-						vol += (ModSinusTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
+-					}
+-				}
+-				if ((m_nTickCount) || ((m_nType & (MOD_TYPE_STM|MOD_TYPE_S3M|MOD_TYPE_IT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))))
+-				{
+-					pChn->nTremoloPos = (trempos + pChn->nTremoloSpeed) & 0x3F;
+-				}
+-			}
+-			// Tremor
+-			if (pChn->nCommand == CMD_TREMOR)
+-			{
+-				UINT n = (pChn->nTremorParam >> 4) + (pChn->nTremorParam & 0x0F);
+-				UINT ontime = pChn->nTremorParam >> 4;
+-				if ((!(m_nType & MOD_TYPE_IT)) || (m_dwSongFlags & SONG_ITOLDEFFECTS)) { n += 2; ontime++; }
+-				UINT tremcount = (UINT)pChn->nTremorCount;
+-				if (tremcount >= n) tremcount = 0;
+-				if ((m_nTickCount) || (m_nType & (MOD_TYPE_S3M|MOD_TYPE_IT)))
+-				{
+-					if (tremcount >= ontime) vol = 0;
+-					pChn->nTremorCount = (BYTE)(tremcount + 1);
+-				}
+-				pChn->dwFlags |= CHN_FASTVOLRAMP;
+-			}
+-			// Clip volume
+-			if (vol < 0) vol = 0;
+-			if (vol > 0x100) vol = 0x100;
+-			vol <<= 6;
+-			// Process Envelopes
+-			if ((m_dwSongFlags & SONG_INSTRUMENTMODE) && pChn->pHeader)
+-			{
+-				INSTRUMENTHEADER *penv = pChn->pHeader;
+-				// Volume Envelope
+-				if ((pChn->dwFlags & CHN_VOLENV) && (penv->VolEnv.nNodes))
+-				{
+-					int envpos = pChn->nVolEnvPosition;
+-					UINT pt = penv->VolEnv.nNodes - 1;
+-					for (UINT i=0; i<(UINT)(penv->VolEnv.nNodes-1); i++)
+-					{
+-						if (envpos <= penv->VolEnv.Ticks[i])
+-						{
+-							pt = i;
+-							break;
+-						}
+-					}
+-					int x2 = penv->VolEnv.Ticks[pt];
+-					int x1, envvol;
+-					if (envpos >= x2)
+-					{
+-						envvol = penv->VolEnv.Values[pt] << 2;
+-						x1 = x2;
+-					} else
+-					if (pt)
+-					{
+-						envvol = penv->VolEnv.Values[pt-1] << 2;
+-						x1 = penv->VolEnv.Ticks[pt-1];
+-					} else
+-					{
+-						envvol = 0;
+-						x1 = 0;
+-					}
+-					if (envpos > x2) envpos = x2;
+-					if ((x2 > x1) && (envpos > x1))
+-					{
+-						envvol += ((envpos - x1) * (((int)penv->VolEnv.Values[pt]<<2) - envvol)) / (x2 - x1);
+-					}
+-					if (envvol < 0) envvol = 0;
+-					if (envvol > 256) envvol = 256;
+-					vol = (vol * envvol) >> 8;
+-				}
+-				// Panning Envelope
+-				if ((pChn->dwFlags & CHN_PANENV) && (penv->PanEnv.nNodes))
+-				{
+-					int envpos = pChn->nPanEnvPosition;
+-					UINT pt = penv->PanEnv.nNodes - 1;
+-					for (UINT i=0; i<(UINT)(penv->PanEnv.nNodes-1); i++)
+-					{
+-						if (envpos <= penv->PanEnv.Ticks[i])
+-						{
+-							pt = i;
+-							break;
+-						}
+-					}
+-					int x2 = penv->PanEnv.Ticks[pt], y2 = penv->PanEnv.Values[pt];
+-					int x1, envpan;
+-					if (envpos >= x2)
+-					{
+-						envpan = y2;
+-						x1 = x2;
+-					} else
+-					if (pt)
+-					{
+-						envpan = penv->PanEnv.Values[pt-1];
+-						x1 = penv->PanEnv.Ticks[pt-1];
+-					} else
+-					{
+-						envpan = 128;
+-						x1 = 0;
+-					}
+-					if ((x2 > x1) && (envpos > x1))
+-					{
+-						envpan += ((envpos - x1) * (y2 - envpan)) / (x2 - x1);
+-					}
+-					if (envpan < 0) envpan = 0;
+-					if (envpan > 64) envpan = 64;
+-					int pan = pChn->nPan;
+-					if (pan >= 128)
+-					{
+-						pan += ((envpan - 32) * (256 - pan)) / 32;
+-					} else
+-					{
+-						pan += ((envpan - 32) * (pan)) / 32;
+-					}
+-					if (pan < 0) pan = 0;
+-					if (pan > 256) pan = 256;
+-					pChn->nRealPan = pan;
+-				}
+-				// FadeOut volume
+-				if (pChn->dwFlags & CHN_NOTEFADE)
+-				{
+-					UINT fadeout = penv->nFadeOut;
+-					if (fadeout)
+-					{
+-						pChn->nFadeOutVol -= fadeout << 1;
+-						if (pChn->nFadeOutVol <= 0) pChn->nFadeOutVol = 0;
+-						vol = (vol * pChn->nFadeOutVol) >> 16;
+-					} else
+-					if (!pChn->nFadeOutVol)
+-					{
+-						vol = 0;
+-					}
+-				}
+-				// Pitch/Pan separation
+-				if ((penv->nPPS) && (pChn->nRealPan) && (pChn->nNote))
+-				{
+-					int pandelta = (int)pChn->nRealPan + (int)((int)(pChn->nNote - penv->nPPC - 1) * (int)penv->nPPS) / (int)8;
+-					if (pandelta < 0) pandelta = 0;
+-					if (pandelta > 256) pandelta = 256;
+-					pChn->nRealPan = pandelta;
+-				}
+-			} else
+-			{
+-				// No Envelope: key off => note cut
+-				if (pChn->dwFlags & CHN_NOTEFADE) // 1.41-: CHN_KEYOFF|CHN_NOTEFADE
+-				{
+-					pChn->nFadeOutVol = 0;
+-					vol = 0;
+-				}
+-			}
+-			// vol is 14-bits
+-			if (vol)
+-			{
+-				// IMPORTANT: pChn->nRealVolume is 14 bits !!!
+-				// -> _muldiv( 14+8, 6+6, 18); => RealVolume: 14-bit result (22+12-20)
+-				pChn->nRealVolume = _muldiv(vol * m_nGlobalVolume, pChn->nGlobalVol * pChn->nInsVol, 1 << 20);
+-			}
+-			if (pChn->nPeriod < m_nMinPeriod) pChn->nPeriod = m_nMinPeriod;
+-			int period = pChn->nPeriod;
+-			if ((pChn->dwFlags & (CHN_GLISSANDO|CHN_PORTAMENTO)) ==	(CHN_GLISSANDO|CHN_PORTAMENTO))
+-			{
+-				period = GetPeriodFromNote(GetNoteFromPeriod(period), pChn->nFineTune, pChn->nC4Speed);
+-			}
+-
+-			// Arpeggio ?
+-			if (pChn->nCommand == CMD_ARPEGGIO)
+-			{
+-				switch(m_nTickCount % 3)
+-				{
+-#if 0
+-				case 1:	period = GetPeriodFromNote(pChn->nNote + (pChn->nArpeggio >> 4), pChn->nFineTune, pChn->nC4Speed); break;
+-				case 2:	period = GetPeriodFromNote(pChn->nNote + (pChn->nArpeggio & 0x0F), pChn->nFineTune, pChn->nC4Speed); break;
+-#else
+-				case 1:	period = GetLinearPeriodFromNote(GetNoteFromPeriod(period) + (pChn->nArpeggio >> 4), pChn->nFineTune, pChn->nC4Speed); break;
+-				case 2:	period = GetLinearPeriodFromNote(GetNoteFromPeriod(period) + (pChn->nArpeggio & 0x0F), pChn->nFineTune, pChn->nC4Speed); break;
+-#endif
+-				}
+-			}
+-
+-			if (m_dwSongFlags & SONG_AMIGALIMITS)
+-			{
+-				if (period < 113*4) period = 113*4;
+-				if (period > 856*4) period = 856*4;
+-			}
+-
+-			// Pitch/Filter Envelope
+-			int envpitch = 0;
+-			if ((m_dwSongFlags & SONG_INSTRUMENTMODE) && (pChn->pHeader)
+-			    && (pChn->dwFlags & CHN_PITCHENV) && (pChn->pHeader->PitchEnv.nNodes))
+-			{
+-				INSTRUMENTHEADER *penv = pChn->pHeader;
+-				int envpos = pChn->nPitchEnvPosition;
+-				UINT pt = penv->PitchEnv.nNodes - 1;
+-				for (UINT i=0; i<(UINT)(penv->PitchEnv.nNodes-1); i++)
+-				{
+-					if (envpos <= penv->PitchEnv.Ticks[i])
+-					{
+-						pt = i;
+-						break;
+-					}
+-				}
+-				int x2 = penv->PitchEnv.Ticks[pt];
+-				int x1;
+-				if (envpos >= x2)
+-				{
+-					envpitch = (((int)penv->PitchEnv.Values[pt]) - 32) * 8;
+-					x1 = x2;
+-				} else
+-				if (pt)
+-				{
+-					envpitch = (((int)penv->PitchEnv.Values[pt-1]) - 32) * 8;
+-					x1 = penv->PitchEnv.Ticks[pt-1];
+-				} else
+-				{
+-					envpitch = 0;
+-					x1 = 0;
+-				}
+-				if (envpos > x2) envpos = x2;
+-				if ((x2 > x1) && (envpos > x1))
+-				{
+-					int envpitchdest = (((int)penv->PitchEnv.Values[pt]) - 32) * 8;
+-					envpitch += ((envpos - x1) * (envpitchdest - envpitch)) / (x2 - x1);
+-				}
+-				if (envpitch < -256) envpitch = -256;
+-				if (envpitch > 256) envpitch = 256;
+-				// Pitch Envelope
+-				if (!(penv->dwFlags & ENV_FILTER))
+-				{
+-					int l = envpitch;
+-					if (l < 0)
+-					{
+-						l = -l;
+-						if (l > 255) l = 255;
+-						period = _muldiv(period, LinearSlideUpTable[l], 0x10000);
+-					} else
+-					{
+-						if (l > 255) l = 255;
+-						period = _muldiv(period, LinearSlideDownTable[l], 0x10000);
+-					}
+-				}
+-			}
+-
+-			// Vibrato
+-			if (pChn->dwFlags & CHN_VIBRATO)
+-			{
+-				UINT vibpos = pChn->nVibratoPos;
+-				LONG vdelta;
+-				switch (pChn->nVibratoType & 0x03)
+-				{
+-				case 1:
+-					vdelta = ModRampDownTable[vibpos];
+-					break;
+-				case 2:
+-					vdelta = ModSquareTable[vibpos];
+-					break;
+-				case 3:
+-					vdelta = ModRandomTable[vibpos];
+-					break;
+-				default:
+-					vdelta = ModSinusTable[vibpos];
+-				}
+-				UINT vdepth = ((m_nType != MOD_TYPE_IT) || (m_dwSongFlags & SONG_ITOLDEFFECTS)) ? 6 : 7;
+-				vdelta = (vdelta * (int)pChn->nVibratoDepth) >> vdepth;
+-				if ((m_dwSongFlags & SONG_LINEARSLIDES) && (m_nType & MOD_TYPE_IT))
+-				{
+-					LONG l = vdelta;
+-					if (l < 0)
+-					{
+-						l = -l;
+-						vdelta = _muldiv(period, LinearSlideDownTable[l >> 2], 0x10000) - period;
+-						if (l & 0x03) vdelta += _muldiv(period, FineLinearSlideDownTable[l & 0x03], 0x10000) - period;
+-
+-					} else
+-					{
+-						vdelta = _muldiv(period, LinearSlideUpTable[l >> 2], 0x10000) - period;
+-						if (l & 0x03) vdelta += _muldiv(period, FineLinearSlideUpTable[l & 0x03], 0x10000) - period;
+-
+-					}
+-				}
+-				period += vdelta;
+-				if ((m_nTickCount) || ((m_nType & MOD_TYPE_IT) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))))
+-				{
+-					pChn->nVibratoPos = (vibpos + pChn->nVibratoSpeed) & 0x3F;
+-				}
+-			}
+-			// Panbrello
+-			if (pChn->dwFlags & CHN_PANBRELLO)
+-			{
+-				UINT panpos = ((pChn->nPanbrelloPos+0x10) >> 2) & 0x3F;
+-				LONG pdelta;
+-				switch (pChn->nPanbrelloType & 0x03)
+-				{
+-				case 1:
+-					pdelta = ModRampDownTable[panpos];
+-					break;
+-				case 2:
+-					pdelta = ModSquareTable[panpos];
+-					break;
+-				case 3:
+-					pdelta = ModRandomTable[panpos];
+-					break;
+-				default:
+-					pdelta = ModSinusTable[panpos];
+-				}
+-				pChn->nPanbrelloPos += pChn->nPanbrelloSpeed;
+-				pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> 3;
+-				pdelta += pChn->nRealPan;
+-				if (pdelta < 0) pdelta = 0;
+-				if (pdelta > 256) pdelta = 256;
+-				pChn->nRealPan = pdelta;
+-			}
+-			int nPeriodFrac = 0;
+-			// Instrument Auto-Vibrato
+-			if ((pChn->pInstrument) && (pChn->pInstrument->nVibDepth))
+-			{
+-				MODINSTRUMENT *pins = pChn->pInstrument;
+-				/* this isn't correct, but its better... */
+-
+-				if (pins->nVibSweep == 0) {
+-					pChn->nAutoVibDepth = pins->nVibDepth << 8;
+-				} else {
+-					pChn->nAutoVibDepth += pins->nVibSweep;
+-					if ((pChn->nAutoVibDepth >> 8) > (int)pins->nVibDepth)
+-						pChn->nAutoVibDepth = pins->nVibDepth << 8;
+-				}
+-#if 0
+-				if (pins->nVibSweep == 0)
+-				{
+-					pChn->nAutoVibDepth = pins->nVibDepth << 8;
+-				} else
+-				{
+-					if (m_nType & MOD_TYPE_IT)
+-					{
+-						pChn->nAutoVibDepth += pins->nVibSweep;
+-					} else
+-					if (!(pChn->dwFlags & CHN_KEYOFF))
+-					{
+-						pChn->nAutoVibDepth += (pins->nVibDepth << 8) /	pins->nVibSweep;
+-					}
+-					if ((pChn->nAutoVibDepth >> 8) > pins->nVibDepth)
+-						pChn->nAutoVibDepth = pins->nVibDepth << 8;
+-				}
+-#endif
+-				pChn->nAutoVibPos += ((int)pins->nVibRate);
+-				int val;
+-				switch(pins->nVibType)
+-				{
+-				case 4:	// Random
+-					val = ModRandomTable[pChn->nAutoVibPos & 0x3F];
+-					pChn->nAutoVibPos++;
+-					break;
+-				case 3:	// Ramp Down
+-					val = ((0x40 - (pChn->nAutoVibPos >> 1)) & 0x7F) - 0x40;
+-					break;
+-				case 2:	// Ramp Up
+-					val = ((0x40 + (pChn->nAutoVibPos >> 1)) & 0x7f) - 0x40;
+-					break;
+-				case 1:	// Square
+-					val = (pChn->nAutoVibPos & 128) ? +64 : -64;
+-					break;
+-				default:	// Sine
+-					val = ft2VibratoTable[pChn->nAutoVibPos & 255];
+-				}
+-				int n =	((val * pChn->nAutoVibDepth) >> 8);
+-				// is this right? -mrsb
+-				if (!(m_dwSongFlags & SONG_ITOLDEFFECTS))
+-					n >>= 1;
+-
+-				if (m_nType & MOD_TYPE_IT)
+-				{
+-					int df1, df2;
+-					if (n < 0)
+-					{
+-						n = -n;
+-						UINT n1 = n >> 8;
+-						df1 = LinearSlideUpTable[n1];
+-						df2 = LinearSlideUpTable[n1+1];
+-					} else
+-					{
+-						UINT n1 = n >> 8;
+-						df1 = LinearSlideDownTable[n1];
+-						df2 = LinearSlideDownTable[n1+1];
+-					}
+-					n >>= 2;
+-					period = _muldiv(period, df1 + ((df2-df1)*(n&0x3F)>>6), 256);
+-					nPeriodFrac = period & 0xFF;
+-					period >>= 8;
+-				} else
+-				{
+-					period += (n >> 6);
+-				}
+-			}
+-			// Final Period
+-			if (period <= m_nMinPeriod)
+-			{
+-				if (m_nType & MOD_TYPE_S3M) pChn->nLength = 0;
+-				period = m_nMinPeriod;
+-			}
+-			if (period > m_nMaxPeriod)
+-			{
+-				if ((m_nType & MOD_TYPE_IT) || (period >= 0x100000))
+-				{
+-					pChn->nFadeOutVol = 0;
+-					pChn->dwFlags |= CHN_NOTEFADE;
+-					pChn->nRealVolume = 0;
+-				}
+-				period = m_nMaxPeriod;
+-				nPeriodFrac = 0;
+-			}
+-			UINT freq = GetFreqFromPeriod(period, pChn->nC4Speed, nPeriodFrac);
+-
+-			// Filter Envelope: controls cutoff frequency
+-			if (pChn && pChn->pHeader && pChn->pHeader->dwFlags & ENV_FILTER)
+-			{
+-#ifndef NO_FILTER
+-				SetupChannelFilter(pChn, (pChn->dwFlags & CHN_FILTER) ? FALSE : TRUE, envpitch);
+-#endif // NO_FILTER
+-			}
+-
+-#if 0
+-			if ((m_nType & MOD_TYPE_IT) && (freq < 256))
+-			{
+-				pChn->nFadeOutVol = 0;
+-				pChn->dwFlags |= CHN_NOTEFADE;
+-				pChn->nRealVolume = 0;
+-			}
+-#endif
+-			pChn->sample_freq = freq;
+-
+-			UINT ninc = _muldiv(freq, 0x10000, gdwMixingFreq);
+-			if ((ninc >= 0xFFB0) && (ninc <= 0x10090)) ninc = 0x10000;
+-			if (m_nFreqFactor != 128) ninc = (ninc * m_nFreqFactor) >> 7;
+-			if (ninc > 0xFF0000) ninc = 0xFF0000;
+-			pChn->nInc = (ninc+1) & ~3;
+-		}
+-
+-		// Increment envelope position
+-		if ((m_dwSongFlags & SONG_INSTRUMENTMODE) && pChn->pHeader)
+-		{
+-			INSTRUMENTHEADER *penv = pChn->pHeader;
+-			// Volume Envelope
+-			if (pChn->dwFlags & CHN_VOLENV)
+-			{
+-				// Increase position
+-				pChn->nVolEnvPosition++;
+-				// Volume Loop ?
+-				if (penv->dwFlags & ENV_VOLLOOP)
+-				{
+-					int volloopend = penv->VolEnv.Ticks[penv->VolEnv.nLoopEnd];
+-					if (m_nType != MOD_TYPE_XM) volloopend++;
+-					if (pChn->nVolEnvPosition == volloopend)
+-					{
+-						pChn->nVolEnvPosition = penv->VolEnv.Ticks[penv->VolEnv.nLoopStart];
+-						if ((penv->VolEnv.nLoopEnd == penv->VolEnv.nLoopStart) && (!penv->VolEnv.Values[penv->VolEnv.nLoopStart])
+-						 && ((!(m_nType & MOD_TYPE_XM)) || (penv->VolEnv.nLoopEnd+1 == penv->VolEnv.nNodes)))
+-						{
+-							pChn->dwFlags |= CHN_NOTEFADE;
+-							pChn->nFadeOutVol = 0;
+-						}
+-					}
+-				}
+-				// Volume Sustain ?
+-				if ((penv->dwFlags & ENV_VOLSUSTAIN) && (!(pChn->dwFlags & CHN_KEYOFF)))
+-				{
+-					if (pChn->nVolEnvPosition == (int)penv->VolEnv.Ticks[penv->VolEnv.nSustainEnd]+1)
+-						pChn->nVolEnvPosition = penv->VolEnv.Ticks[penv->VolEnv.nSustainStart];
+-				} else
+-				// End of Envelope ?
+-				if (pChn->nVolEnvPosition > penv->VolEnv.Ticks[penv->VolEnv.nNodes - 1])
+-				{
+-					if ((m_nType & MOD_TYPE_IT) || (pChn->dwFlags & CHN_KEYOFF)) pChn->dwFlags |= CHN_NOTEFADE;
+-					pChn->nVolEnvPosition = penv->VolEnv.Ticks[penv->VolEnv.nNodes - 1];
+-					if ((!penv->VolEnv.Values[penv->VolEnv.nNodes-1]) && ((nChn >= m_nChannels) || (m_nType & MOD_TYPE_IT)))
+-					{
+-						pChn->dwFlags |= CHN_NOTEFADE;
+-						pChn->nFadeOutVol = 0;
+-
+-						pChn->nRealVolume = 0;
+-					}
+-				}
+-			}
+-			// Panning Envelope
+-			if (pChn->dwFlags & CHN_PANENV)
+-			{
+-				pChn->nPanEnvPosition++;
+-				if (penv->dwFlags & ENV_PANLOOP)
+-				{
+-					int panloopend = penv->PanEnv.Ticks[penv->PanEnv.nLoopEnd];
+-					if (m_nType != MOD_TYPE_XM) panloopend++;
+-					if (pChn->nPanEnvPosition == panloopend)
+-						pChn->nPanEnvPosition = penv->PanEnv.Ticks[penv->PanEnv.nLoopStart];
+-				}
+-				// Panning Sustain ?
+-				if ((penv->dwFlags & ENV_PANSUSTAIN) && (pChn->nPanEnvPosition == (int)penv->PanEnv.Ticks[penv->PanEnv.nSustainEnd]+1)
+-				 && (!(pChn->dwFlags & CHN_KEYOFF)))
+-				{
+-					// Panning sustained
+-					pChn->nPanEnvPosition = penv->PanEnv.Ticks[penv->PanEnv.nSustainStart];
+-				} else
+-				{
+-					if (pChn->nPanEnvPosition > penv->PanEnv.Ticks[penv->PanEnv.nNodes - 1])
+-						pChn->nPanEnvPosition = penv->PanEnv.Ticks[penv->PanEnv.nNodes - 1];
+-				}
+-			}
+-			// Pitch Envelope
+-			if (pChn->dwFlags & CHN_PITCHENV)
+-			{
+-				// Increase position
+-				pChn->nPitchEnvPosition++;
+-				// Pitch Loop ?
+-				if (penv->dwFlags & ENV_PITCHLOOP)
+-				{
+-					if (pChn->nPitchEnvPosition >= penv->PitchEnv.Ticks[penv->PitchEnv.nLoopEnd])
+-						pChn->nPitchEnvPosition = penv->PitchEnv.Ticks[penv->PitchEnv.nLoopStart];
+-				}
+-				// Pitch Sustain ?
+-				if ((penv->dwFlags & ENV_PITCHSUSTAIN) && (!(pChn->dwFlags & CHN_KEYOFF)))
+-				{
+-					if (pChn->nPitchEnvPosition == (int)penv->PitchEnv.Ticks[penv->PitchEnv.nSustainEnd]+1)
+-						pChn->nPitchEnvPosition = penv->PitchEnv.Ticks[penv->PitchEnv.nSustainStart];
+-				} else
+-				{
+-					if (pChn->nPitchEnvPosition > penv->PitchEnv.Ticks[penv->PitchEnv.nNodes - 1])
+-						pChn->nPitchEnvPosition = penv->PitchEnv.Ticks[penv->PitchEnv.nNodes - 1];
+-				}
+-			}
+-		}
+-#if 0
+-		// Limit CPU -> > 80% -> don't ramp
+-		if ((gnCPUUsage >= 80) && (!pChn->nRealVolume))
+-		{
+-			pChn->nLeftVol = pChn->nRightVol = 0;
+-		}
+-#endif // MODPLUG_PLAYER
+-		// Volume ramping
+-		pChn->dwFlags &= ~CHN_VOLUMERAMP;
+-		if ((pChn->nRealVolume) || (pChn->nLeftVol) || (pChn->nRightVol))
+-			pChn->dwFlags |= CHN_VOLUMERAMP;
+-		// Decrease VU-Meter
+-		if (pChn->nVUMeter > VUMETER_DECAY)	pChn->nVUMeter -= VUMETER_DECAY; else pChn->nVUMeter = 0;
+-		if (pChn->nLeftVU > VUMETER_DECAY) pChn->nLeftVU -= VUMETER_DECAY; else pChn->nLeftVU = 0;
+-		if (pChn->nRightVU > VUMETER_DECAY) pChn->nRightVU -= VUMETER_DECAY; else pChn->nRightVU = 0;
+-		// Check for too big nInc
+-		if (((pChn->nInc >> 16) + 1) >= (LONG)(pChn->nLoopEnd - pChn->nLoopStart)) pChn->dwFlags &= ~CHN_LOOP;
+-		pChn->nNewRightVol = pChn->nNewLeftVol = 0;
+-		pChn->pCurrentSample = ((pChn->pSample) && (pChn->nLength) && (pChn->nInc)) ? pChn->pSample : NULL;
+-		if (pChn->pCurrentSample)
+-		{
+-			// Update VU-Meter (nRealVolume is 14-bit)
+-			UINT vutmp = pChn->nRealVolume >> (14 - 8);
+-			if (vutmp > 0xFF) vutmp = 0xFF;
+-			if (pChn->nVUMeter >= 0x100) pChn->nVUMeter = vutmp;
+-			vutmp >>= 1;
+-			if (pChn->nVUMeter < vutmp)	pChn->nVUMeter = vutmp;
+-			UINT vul = (pChn->nRealVolume * pChn->nRealPan) >> 14;
+-			if (vul > 127) vul = 127;
+-			if (pChn->nLeftVU > 127) pChn->nLeftVU = (BYTE)vul;
+-			vul >>= 1;
+-			if (pChn->nLeftVU < vul) pChn->nLeftVU = (BYTE)vul;
+-			UINT vur = (pChn->nRealVolume * (256-pChn->nRealPan)) >> 14;
+-			if (vur > 127) vur = 127;
+-			if (pChn->nRightVU > 127) pChn->nRightVU = (BYTE)vur;
+-			vur >>= 1;
+-			if (pChn->nRightVU < vur) pChn->nRightVU = (BYTE)vur;
+-#ifdef MODPLUG_TRACKER
+-			UINT kChnMasterVol = (pChn->dwFlags & CHN_EXTRALOUD) ? 0x100 : nMasterVol;
+-#else
+-#define		kChnMasterVol	nMasterVol
+-#endif // MODPLUG_TRACKER
+-			// Adjusting volumes
+-			if (gnChannels >= 2)
+-			{
+-				int pan = ((int)pChn->nRealPan) - 128;
+-				pan *= (int)m_nStereoSeparation;
+-				pan /= 128;
+-				pan += 128;
+-
+-				if (pan < 0) pan = 0;
+-				if (pan > 256) pan = 256;
+-				if (gdwSoundSetup & SNDMIX_REVERSESTEREO) pan = 256 - pan;
+-				if (m_dwSongFlags & SONG_NOSTEREO) pan = 128;
+-				LONG realvol = (pChn->nRealVolume * kChnMasterVol) >> (8-1);
+-				if (gdwSoundSetup & SNDMIX_SOFTPANNING)
+-				{
+-					if (pan < 128)
+-					{
+-						pChn->nNewLeftVol = (realvol * pan) >> 8;
+-						pChn->nNewRightVol = (realvol * 128) >> 8;
+-					} else
+-					{
+-						pChn->nNewLeftVol = (realvol * 128) >> 8;
+-						pChn->nNewRightVol = (realvol * (256 - pan)) >> 8;
+-					}
+-				} else
+-				{
+-					pChn->nNewLeftVol = (realvol * pan) >> 8;
+-					pChn->nNewRightVol = (realvol * (256 - pan)) >> 8;
+-				}
+-			} else
+-			{
+-				pChn->nNewRightVol = (pChn->nRealVolume * kChnMasterVol) >> 8;
+-				pChn->nNewLeftVol = pChn->nNewRightVol;
+-			}
+-			// Clipping volumes
+-			if (pChn->nNewRightVol > 0xFFFF) pChn->nNewRightVol = 0xFFFF;
+-			if (pChn->nNewLeftVol > 0xFFFF) pChn->nNewLeftVol = 0xFFFF;
+-			// Check IDO
+-			if (gdwSoundSetup & SNDMIX_NORESAMPLING)
+-			{
+-				pChn->dwFlags &= ~(CHN_HQSRC);
+-				pChn->dwFlags |= CHN_NOIDO;
+-			} else
+-			{
+-				pChn->dwFlags &= ~(CHN_NOIDO|CHN_HQSRC);
+-				if( pChn->nInc == 0x10000 )
+-				{	pChn->dwFlags |= CHN_NOIDO;
+-				}
+-				else
+-				{	if( ((gdwSoundSetup & SNDMIX_HQRESAMPLER) == 0) && ((gdwSoundSetup & SNDMIX_ULTRAHQSRCMODE) == 0) )
+-					{	if (pChn->nInc >= 0xFF00) pChn->dwFlags |= CHN_NOIDO;
+-					}
+-				}
+-			}
+-			pChn->nNewRightVol >>= MIXING_ATTENUATION;
+-			pChn->nNewLeftVol >>= MIXING_ATTENUATION;
+-			pChn->nRightRamp = pChn->nLeftRamp = 0;
+-			// Dolby Pro-Logic Surround
+-			if ((pChn->dwFlags & CHN_SURROUND) && (gnChannels <= 2) && (gdwSoundSetup & SNDMIX_NOSURROUND) == 0)
+-				pChn->nNewLeftVol = -pChn->nNewLeftVol;
+-			// Checking Ping-Pong Loops
+-			if (pChn->dwFlags & CHN_PINGPONGFLAG) pChn->nInc = -pChn->nInc;
+-			// Setting up volume ramp
+-			if (!(gdwSoundSetup & SNDMIX_NORAMPING)
+-			 && (pChn->dwFlags & CHN_VOLUMERAMP)
+-			 && ((pChn->nRightVol != pChn->nNewRightVol)
+-			  || (pChn->nLeftVol != pChn->nNewLeftVol)))
+-			{
+-				LONG nRampLength = gnVolumeRampSamples;
+-				LONG nRightDelta = ((pChn->nNewRightVol - pChn->nRightVol) << VOLUMERAMPPRECISION);
+-				LONG nLeftDelta = ((pChn->nNewLeftVol - pChn->nLeftVol) << VOLUMERAMPPRECISION);
+-#if 0
+-				if ((gdwSoundSetup & SNDMIX_DIRECTTODISK)
+-				 || ((gdwSysInfo & (SYSMIX_ENABLEMMX|SYSMIX_FASTCPU))
+-				  && (gdwSoundSetup & SNDMIX_HQRESAMPLER) && (gnCPUUsage <= 20)))
+-#else
+-				if (gdwSoundSetup & SNDMIX_HQRESAMPLER)
+-#endif
+-				{
+-					if ((pChn->nRightVol|pChn->nLeftVol) && (pChn->nNewRightVol|pChn->nNewLeftVol) && (!(pChn->dwFlags & CHN_FASTVOLRAMP)))
+-					{
+-						nRampLength = m_nBufferCount;
+-						if (nRampLength > (1 << (VOLUMERAMPPRECISION-1))) nRampLength = (1 << (VOLUMERAMPPRECISION-1));
+-						if (nRampLength < (LONG)gnVolumeRampSamples) nRampLength = gnVolumeRampSamples;
+-					}
+-				}
+-				pChn->nRightRamp = nRightDelta / nRampLength;
+-				pChn->nLeftRamp = nLeftDelta / nRampLength;
+-				pChn->nRightVol = pChn->nNewRightVol - ((pChn->nRightRamp * nRampLength) >> VOLUMERAMPPRECISION);
+-				pChn->nLeftVol = pChn->nNewLeftVol - ((pChn->nLeftRamp * nRampLength) >> VOLUMERAMPPRECISION);
+-				if (pChn->nRightRamp|pChn->nLeftRamp)
+-				{
+-					pChn->nRampLength = nRampLength;
+-				} else
+-				{
+-					pChn->dwFlags &= ~CHN_VOLUMERAMP;
+-					pChn->nRightVol = pChn->nNewRightVol;
+-					pChn->nLeftVol = pChn->nNewLeftVol;
+-				}
+-			} else
+-			{
+-				pChn->dwFlags &= ~CHN_VOLUMERAMP;
+-				pChn->nRightVol = pChn->nNewRightVol;
+-				pChn->nLeftVol = pChn->nNewLeftVol;
+-			}
+-			pChn->nRampRightVol = pChn->nRightVol << VOLUMERAMPPRECISION;
+-			pChn->nRampLeftVol = pChn->nLeftVol << VOLUMERAMPPRECISION;
+-			// Adding the channel in the channel list
+-			if (!(pChn->dwFlags & CHN_MUTE)) {
+-				ChnMix[m_nMixChannels++] = nChn;
+-				if (m_nMixChannels >= MAX_CHANNELS) break;
+-			}
+-		} else
+-		{
+-			// Note change but no sample
+-			if (pChn->nLeftVU > 128) pChn->nLeftVU = 0;
+-			if (pChn->nRightVU > 128) pChn->nRightVU = 0;
+-			if (pChn->nVUMeter > 0xFF) pChn->nVUMeter = 0;
+-			pChn->nLeftVol = pChn->nRightVol = 0;
+-			pChn->nLength = 0;
+-		}
+-	}
+-	// Checking Max Mix Channels reached: ordering by volume
+-	if ((m_nMixChannels >= m_nMaxMixChannels) && (!(gdwSoundSetup & SNDMIX_DIRECTTODISK)))
+-	{
+-		for (UINT i=0; i<m_nMixChannels; i++)
+-		{
+-			UINT j=i;
+-			while ((j+1<m_nMixChannels) && (Chn[ChnMix[j]].nRealVolume < Chn[ChnMix[j+1]].nRealVolume))
+-			{
+-				UINT n = ChnMix[j];
+-				ChnMix[j] = ChnMix[j+1];
+-				ChnMix[j+1] = n;
+-				j++;
+-			}
+-		}
+-	}
+-	if (m_dwSongFlags & SONG_GLOBALFADE)
+-	{
+-		if (!m_nGlobalFadeSamples)
+-		{
+-			m_dwSongFlags |= SONG_ENDREACHED;
+-			return FALSE;
+-		}
+-		if (m_nGlobalFadeSamples > m_nBufferCount)
+-			m_nGlobalFadeSamples -= m_nBufferCount;
+-		else
+-			m_nGlobalFadeSamples = 0;
+-	}
+-	return TRUE;
+-}
+-
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/stdafx.h audacious-plugins-2.5.4/src/modplug/stdafx.h
+--- audacious-plugins-2.5.4-orig/src/modplug/stdafx.h	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/stdafx.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,94 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Rani Assaf <rani at magic.metawire.com>,
+- *          Olivier Lapicque <olivierl at jps.net>,
+- *          Adam Goode       <adam at evdebs.org> (endian and char fixes for PPC)
+-*/
+-
+-#ifndef _STDAFX_H_
+-#define _STDAFX_H_
+-
+-#ifdef MSC_VER
+-
+-#pragma warning (disable:4201)
+-#pragma warning (disable:4514)
+-#include <windows.h>
+-#include <windowsx.h>
+-#include <mmsystem.h>
+-#include <stdio.h>
+-
+-inline void ProcessPlugins(int n) {}
+-
+-#else
+-
+-#include <stdlib.h>
+-#include <stdio.h>
+-#include <string.h>
+-
+-typedef signed char CHAR;
+-typedef unsigned char UCHAR;
+-typedef unsigned char* PUCHAR;
+-typedef unsigned short USHORT;
+-typedef unsigned int ULONG;
+-typedef unsigned int UINT;
+-typedef unsigned int DWORD;
+-typedef int LONG;
+-typedef unsigned short WORD;
+-typedef unsigned char BYTE;
+-typedef unsigned char * LPBYTE;
+-#ifdef __cplusplus
+-typedef bool BOOL;
+-#endif
+-typedef char * LPSTR;
+-typedef void *  LPVOID;
+-typedef int * LPLONG;
+-typedef unsigned int * LPDWORD;
+-typedef unsigned short * LPWORD;
+-typedef const char * LPCSTR;
+-typedef long long LONGLONG;
+-typedef void * PVOID;
+-typedef void VOID;
+-
+-
+-#define NO_AGC
+-#define LPCTSTR LPCSTR
+-#define lstrcpyn strncpy
+-#define lstrcpy strcpy
+-#define lstrcmp strcmp
+-#define WAVE_FORMAT_PCM 1
+-//#define ENABLE_EQ
+-
+-#define  GHND   0
+-
+-#ifdef __cplusplus
+-inline signed char * GlobalAllocPtr(unsigned int, size_t size)
+-{
+-  signed char * p = (signed char *) malloc(size);
+-
+-  if (p != NULL) memset(p, 0, size);
+-  return p;
+-}
+-
+-inline void ProcessPlugins(int) {}
+-
+-#define GlobalFreePtr(p) free((void *)(p))
+-
+-#define strnicmp(a,b,c)		strncasecmp(a,b,c)
+-#define wsprintf			sprintf
+-#endif
+-
+-#ifndef FALSE
+-#define FALSE	false
+-#endif
+-
+-#ifndef TRUE
+-#define TRUE	true
+-#endif
+-
+-#endif // MSC_VER
+-
+-#endif
+-
+-
+-
+diff -Nur audacious-plugins-2.5.4-orig/src/modplug/tables.cxx audacious-plugins-2.5.4/src/modplug/tables.cxx
+--- audacious-plugins-2.5.4-orig/src/modplug/tables.cxx	2011-07-15 01:00:39.000000000 +0200
++++ audacious-plugins-2.5.4/src/modplug/tables.cxx	1970-01-01 01:00:00.000000000 +0100
+@@ -1,373 +0,0 @@
+-/*
+- * This source code is public domain.
+- *
+- * Authors: Olivier Lapicque <olivierl at jps.net>
+- */
+-
+-#include "stdafx.h"
+-#include "sndfile.h"
+-
+-BYTE ImpulseTrackerPortaVolCmd[16] =
+-{
+-	0x00, 0x01, 0x04, 0x08, 0x10, 0x20, 0x40, 0x60,
+-	0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+-};
+-
+-// Period table for Protracker octaves 0-5:
+-WORD ProTrackerPeriodTable[6*12] =
+-{
+-	1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,907,
+-	856,808,762,720,678,640,604,570,538,508,480,453,
+-	428,404,381,360,339,320,302,285,269,254,240,226,
+-	214,202,190,180,170,160,151,143,135,127,120,113,
+-	107,101,95,90,85,80,75,71,67,63,60,56,
+-	53,50,47,45,42,40,37,35,33,31,30,28
+-};
+-
+-
+-WORD ProTrackerTunedPeriods[16*12] = 
+-{
+-	1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,907,
+-	1700,1604,1514,1430,1348,1274,1202,1134,1070,1010,954,900,
+-	1688,1592,1504,1418,1340,1264,1194,1126,1064,1004,948,894,
+-	1676,1582,1492,1408,1330,1256,1184,1118,1056,996,940,888,
+-	1664,1570,1482,1398,1320,1246,1176,1110,1048,990,934,882,
+-	1652,1558,1472,1388,1310,1238,1168,1102,1040,982,926,874,
+-	1640,1548,1460,1378,1302,1228,1160,1094,1032,974,920,868,
+-	1628,1536,1450,1368,1292,1220,1150,1086,1026,968,914,862,
+-	1814,1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,
+-	1800,1700,1604,1514,1430,1350,1272,1202,1134,1070,1010,954,
+-	1788,1688,1592,1504,1418,1340,1264,1194,1126,1064,1004,948,
+-	1774,1676,1582,1492,1408,1330,1256,1184,1118,1056,996,940,
+-	1762,1664,1570,1482,1398,1320,1246,1176,1110,1048,988,934,
+-	1750,1652,1558,1472,1388,1310,1238,1168,1102,1040,982,926,
+-	1736,1640,1548,1460,1378,1302,1228,1160,1094,1032,974,920,
+-	1724,1628,1536,1450,1368,1292,1220,1150,1086,1026,968,914 
+-};
+-
+-
+-// S3M C-4 periods
+-WORD FreqS3MTable[16] = 
+-{
+-	1712,1616,1524,1440,1356,1280,
+-	1208,1140,1076,1016,960,907,
+-	0,0,0,0
+-};
+-
+-
+-// S3M FineTune frequencies
+-WORD S3MFineTuneTable[16] = 
+-{
+-	7895,7941,7985,8046,8107,8169,8232,8280,
+-	8363,8413,8463,8529,8581,8651,8723,8757,	// 8363*2^((i-8)/(12*8))
+-};
+-
+-
+-// Sinus table
+-short int ModSinusTable[64] =
+-{
+-	0,12,25,37,49,60,71,81,90,98,106,112,117,122,125,126,
+-	127,126,125,122,117,112,106,98,90,81,71,60,49,37,25,12,
+-	0,-12,-25,-37,-49,-60,-71,-81,-90,-98,-106,-112,-117,-122,-125,-126,
+-	-127,-126,-125,-122,-117,-112,-106,-98,-90,-81,-71,-60,-49,-37,-25,-12
+-};
+-
+-// Triangle wave table (ramp down)
+-short int ModRampDownTable[64] =
+-{
+-	0,-4,-8,-12,-16,-20,-24,-28,-32,-36,-40,-44,-48,-52,-56,-60,
+-	-64,-68,-72,-76,-80,-84,-88,-92,-96,-100,-104,-108,-112,-116,-120,-124,
+-	127,123,119,115,111,107,103,99,95,91,87,83,79,75,71,67,
+-	63,59,55,51,47,43,39,35,31,27,23,19,15,11,7,3
+-};
+-
+-// Square wave table
+-short int ModSquareTable[64] =
+-{
+-	127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+-	127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+-	-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,
+-	-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127,-127
+-};
+-
+-// Random wave table
+-short int ModRandomTable[64] =
+-{
+-	98,-127,-43,88,102,41,-65,-94,125,20,-71,-86,-70,-32,-16,-96,
+-	17,72,107,-5,116,-69,-62,-40,10,-61,65,109,-18,-38,-13,-76,
+-	-23,88,21,-94,8,106,21,-112,6,109,20,-88,-30,9,-127,118,
+-	42,-34,89,-4,-51,-72,21,-29,112,123,84,-101,-92,98,-54,-95
+-};
+-
+-
+-// volume fade tables for Retrig Note:
+-signed char retrigTable1[16] =
+-{ 0, 0, 0, 0, 0, 0, 10, 8, 0, 0, 0, 0, 0, 0, 24, 32 };
+-
+-signed char retrigTable2[16] =
+-{ 0, -1, -2, -4, -8, -16, 0, 0, 0, 1, 2, 4, 8, 16, 0, 0 };
+-
+-
+-
+-
+-WORD XMPeriodTable[104] = 
+-{
+-	907,900,894,887,881,875,868,862,856,850,844,838,832,826,820,814,
+-	808,802,796,791,785,779,774,768,762,757,752,746,741,736,730,725,
+-	720,715,709,704,699,694,689,684,678,675,670,665,660,655,651,646,
+-	640,636,632,628,623,619,614,610,604,601,597,592,588,584,580,575,
+-	570,567,563,559,555,551,547,543,538,535,532,528,524,520,516,513,
+-	508,505,502,498,494,491,487,484,480,477,474,470,467,463,460,457,
+-	453,450,447,443,440,437,434,431
+-};
+-
+-
+-UINT XMLinearTable[768] = 
+-{
+-	535232,534749,534266,533784,533303,532822,532341,531861,
+-	531381,530902,530423,529944,529466,528988,528511,528034,
+-	527558,527082,526607,526131,525657,525183,524709,524236,
+-	523763,523290,522818,522346,521875,521404,520934,520464,
+-	519994,519525,519057,518588,518121,517653,517186,516720,
+-	516253,515788,515322,514858,514393,513929,513465,513002,
+-	512539,512077,511615,511154,510692,510232,509771,509312,
+-	508852,508393,507934,507476,507018,506561,506104,505647,
+-	505191,504735,504280,503825,503371,502917,502463,502010,
+-	501557,501104,500652,500201,499749,499298,498848,498398,
+-	497948,497499,497050,496602,496154,495706,495259,494812,
+-	494366,493920,493474,493029,492585,492140,491696,491253,
+-	490809,490367,489924,489482,489041,488600,488159,487718,
+-	487278,486839,486400,485961,485522,485084,484647,484210,
+-	483773,483336,482900,482465,482029,481595,481160,480726,
+-	480292,479859,479426,478994,478562,478130,477699,477268,
+-	476837,476407,475977,475548,475119,474690,474262,473834,
+-	473407,472979,472553,472126,471701,471275,470850,470425,
+-	470001,469577,469153,468730,468307,467884,467462,467041,
+-	466619,466198,465778,465358,464938,464518,464099,463681,
+-	463262,462844,462427,462010,461593,461177,460760,460345,
+-	459930,459515,459100,458686,458272,457859,457446,457033,
+-	456621,456209,455797,455386,454975,454565,454155,453745,
+-	453336,452927,452518,452110,451702,451294,450887,450481,
+-	450074,449668,449262,448857,448452,448048,447644,447240,
+-	446836,446433,446030,445628,445226,444824,444423,444022,
+-	443622,443221,442821,442422,442023,441624,441226,440828,
+-	440430,440033,439636,439239,438843,438447,438051,437656,
+-	437261,436867,436473,436079,435686,435293,434900,434508,
+-	434116,433724,433333,432942,432551,432161,431771,431382,
+-	430992,430604,430215,429827,429439,429052,428665,428278,
+-	427892,427506,427120,426735,426350,425965,425581,425197,
+-	424813,424430,424047,423665,423283,422901,422519,422138,
+-	421757,421377,420997,420617,420237,419858,419479,419101,
+-	418723,418345,417968,417591,417214,416838,416462,416086,
+-	415711,415336,414961,414586,414212,413839,413465,413092,
+-	412720,412347,411975,411604,411232,410862,410491,410121,
+-	409751,409381,409012,408643,408274,407906,407538,407170,
+-	406803,406436,406069,405703,405337,404971,404606,404241,
+-	403876,403512,403148,402784,402421,402058,401695,401333,
+-	400970,400609,400247,399886,399525,399165,398805,398445,
+-	398086,397727,397368,397009,396651,396293,395936,395579,
+-	395222,394865,394509,394153,393798,393442,393087,392733,
+-	392378,392024,391671,391317,390964,390612,390259,389907,
+-	389556,389204,388853,388502,388152,387802,387452,387102,
+-	386753,386404,386056,385707,385359,385012,384664,384317,
+-	383971,383624,383278,382932,382587,382242,381897,381552,
+-	381208,380864,380521,380177,379834,379492,379149,378807,
+-
+-	378466,378124,377783,377442,377102,376762,376422,376082,
+-	375743,375404,375065,374727,374389,374051,373714,373377,
+-	373040,372703,372367,372031,371695,371360,371025,370690,
+-	370356,370022,369688,369355,369021,368688,368356,368023,
+-	367691,367360,367028,366697,366366,366036,365706,365376,
+-	365046,364717,364388,364059,363731,363403,363075,362747,
+-	362420,362093,361766,361440,361114,360788,360463,360137,
+-	359813,359488,359164,358840,358516,358193,357869,357547,
+-	357224,356902,356580,356258,355937,355616,355295,354974,
+-	354654,354334,354014,353695,353376,353057,352739,352420,
+-	352103,351785,351468,351150,350834,350517,350201,349885,
+-	349569,349254,348939,348624,348310,347995,347682,347368,
+-	347055,346741,346429,346116,345804,345492,345180,344869,
+-	344558,344247,343936,343626,343316,343006,342697,342388,
+-	342079,341770,341462,341154,340846,340539,340231,339924,
+-	339618,339311,339005,338700,338394,338089,337784,337479,
+-	337175,336870,336566,336263,335959,335656,335354,335051,
+-	334749,334447,334145,333844,333542,333242,332941,332641,
+-	332341,332041,331741,331442,331143,330844,330546,330247,
+-	329950,329652,329355,329057,328761,328464,328168,327872,
+-	327576,327280,326985,326690,326395,326101,325807,325513,
+-	325219,324926,324633,324340,324047,323755,323463,323171,
+-	322879,322588,322297,322006,321716,321426,321136,320846,
+-	320557,320267,319978,319690,319401,319113,318825,318538,
+-	318250,317963,317676,317390,317103,316817,316532,316246,
+-	315961,315676,315391,315106,314822,314538,314254,313971,
+-	313688,313405,313122,312839,312557,312275,311994,311712,
+-	311431,311150,310869,310589,310309,310029,309749,309470,
+-	309190,308911,308633,308354,308076,307798,307521,307243,
+-	306966,306689,306412,306136,305860,305584,305308,305033,
+-	304758,304483,304208,303934,303659,303385,303112,302838,
+-	302565,302292,302019,301747,301475,301203,300931,300660,
+-	300388,300117,299847,299576,299306,299036,298766,298497,
+-	298227,297958,297689,297421,297153,296884,296617,296349,
+-	296082,295815,295548,295281,295015,294749,294483,294217,
+-	293952,293686,293421,293157,292892,292628,292364,292100,
+-	291837,291574,291311,291048,290785,290523,290261,289999,
+-	289737,289476,289215,288954,288693,288433,288173,287913,
+-	287653,287393,287134,286875,286616,286358,286099,285841,
+-	285583,285326,285068,284811,284554,284298,284041,283785,
+-	283529,283273,283017,282762,282507,282252,281998,281743,
+-	281489,281235,280981,280728,280475,280222,279969,279716,
+-	279464,279212,278960,278708,278457,278206,277955,277704,
+-	277453,277203,276953,276703,276453,276204,275955,275706,
+-	275457,275209,274960,274712,274465,274217,273970,273722,
+-	273476,273229,272982,272736,272490,272244,271999,271753,
+-	271508,271263,271018,270774,270530,270286,270042,269798,
+-	269555,269312,269069,268826,268583,268341,268099,267857 
+-};
+-
+-
+-signed char ft2VibratoTable[256] = 
+-{
+-	0,-2,-3,-5,-6,-8,-9,-11,-12,-14,-16,-17,-19,-20,-22,-23,
+-	-24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,
+-	-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,
+-	-56,-57,-58,-59,-59,-60,-60,-61,-61,-62,-62,-62,-63,-63,
+-	-63,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-64,-63,-63,
+-	-63,-62,-62,-62,-61,-61,-60,-60,-59,-59,-58,-57,-56,-56,
+-	-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,
+-	-41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26,-24,-23,
+-	-22,-20,-19,-17,-16,-14,-12,-11,-9,-8,-6,-5,-3,-2,0,
+-	2,3,5,6,8,9,11,12,14,16,17,19,20,22,23,24,26,27,29,30,
+-	32,33,34,36,37,38,39,41,42,43,44,45,46,47,48,49,50,51,
+-	52,53,54,55,56,56,57,58,59,59,60,60,61,61,62,62,62,63,
+-	63,63,64,64,64,64,64,64,64,64,64,64,64,63,63,63,62,62,
+-	62,61,61,60,60,59,59,58,57,56,56,55,54,53,52,51,50,49,
+-	48,47,46,45,44,43,42,41,39,38,37,36,34,33,32,30,29,27,
+-	26,24,23,22,20,19,17,16,14,12,11,9,8,6,5,3,2 
+-};
+-
+-
+-
+-DWORD FineLinearSlideUpTable[16] =
+-{
+-	65536, 65595, 65654, 65714,	65773, 65832, 65892, 65951,
+-	66011, 66071, 66130, 66190, 66250, 66309, 66369, 66429
+-};
+-
+-
+-DWORD FineLinearSlideDownTable[16] =
+-{
+-	65535, 65477, 65418, 65359, 65300, 65241, 65182, 65123,
+-	65065, 65006, 64947, 64888, 64830, 64772, 64713, 64645
+-};
+-
+-
+-DWORD LinearSlideUpTable[256] = 
+-{
+-	65536, 65773, 66010, 66249, 66489, 66729, 66971, 67213, 
+-	67456, 67700, 67945, 68190, 68437, 68685, 68933, 69182, 
+-	69432, 69684, 69936, 70189, 70442, 70697, 70953, 71209, 
+-	71467, 71725, 71985, 72245, 72507, 72769, 73032, 73296, 
+-	73561, 73827, 74094, 74362, 74631, 74901, 75172, 75444, 
+-	75717, 75991, 76265, 76541, 76818, 77096, 77375, 77655, 
+-	77935, 78217, 78500, 78784, 79069, 79355, 79642, 79930, 
+-	80219, 80509, 80800, 81093, 81386, 81680, 81976, 82272, 
+-	82570, 82868, 83168, 83469, 83771, 84074, 84378, 84683, 
+-	84989, 85297, 85605, 85915, 86225, 86537, 86850, 87164, 
+-	87480, 87796, 88113, 88432, 88752, 89073, 89395, 89718, 
+-	90043, 90369, 90695, 91023, 91353, 91683, 92015, 92347, 
+-	92681, 93017, 93353, 93691, 94029, 94370, 94711, 95053, 
+-	95397, 95742, 96088, 96436, 96785, 97135, 97486, 97839, 
+-	98193, 98548, 98904, 99262, 99621, 99981, 100343, 100706, 
+-	101070, 101435, 101802, 102170, 102540, 102911, 103283, 103657, 
+-	104031, 104408, 104785, 105164, 105545, 105926, 106309, 106694, 
+-	107080, 107467, 107856, 108246, 108637, 109030, 109425, 109820, 
+-	110217, 110616, 111016, 111418, 111821, 112225, 112631, 113038, 
+-	113447, 113857, 114269, 114682, 115097, 115514, 115931, 116351, 
+-	116771, 117194, 117618, 118043, 118470, 118898, 119328, 119760, 
+-	120193, 120628, 121064, 121502, 121941, 122382, 122825, 123269, 
+-	123715, 124162, 124611, 125062, 125514, 125968, 126424, 126881, 
+-	127340, 127801, 128263, 128727, 129192, 129660, 130129, 130599, 
+-	131072, 131546, 132021, 132499, 132978, 133459, 133942, 134426, 
+-	134912, 135400, 135890, 136381, 136875, 137370, 137866, 138365, 
+-	138865, 139368, 139872, 140378, 140885, 141395, 141906, 142419, 
+-	142935, 143451, 143970, 144491, 145014, 145538, 146064, 146593, 
+-	147123, 147655, 148189, 148725, 149263, 149803, 150344, 150888, 
+-	151434, 151982, 152531, 153083, 153637, 154192, 154750, 155310, 
+-	155871, 156435, 157001, 157569, 158138, 158710, 159284, 159860, 
+-	160439, 161019, 161601, 162186, 162772, 163361, 163952, 164545, 
+-};
+-
+-
+-DWORD LinearSlideDownTable[256] = 
+-{
+-	65536, 65299, 65064, 64830, 64596, 64363, 64131, 63900, 
+-	63670, 63440, 63212, 62984, 62757, 62531, 62305, 62081, 
+-	61857, 61634, 61412, 61191, 60970, 60751, 60532, 60314, 
+-	60096, 59880, 59664, 59449, 59235, 59021, 58809, 58597, 
+-	58385, 58175, 57965, 57757, 57548, 57341, 57134, 56928, 
+-	56723, 56519, 56315, 56112, 55910, 55709, 55508, 55308, 
+-	55108, 54910, 54712, 54515, 54318, 54123, 53928, 53733, 
+-
+-	53540, 53347, 53154, 52963, 52772, 52582, 52392, 52204, 
+-	52015, 51828, 51641, 51455, 51270, 51085, 50901, 50717, 
+-	50535, 50353, 50171, 49990, 49810, 49631, 49452, 49274, 
+-	49096, 48919, 48743, 48567, 48392, 48218, 48044, 47871, 
+-	47698, 47526, 47355, 47185, 47014, 46845, 46676, 46508, 
+-	46340, 46173, 46007, 45841, 45676, 45511, 45347, 45184, 
+-	45021, 44859, 44697, 44536, 44376, 44216, 44056, 43898, 
+-	43740, 43582, 43425, 43268, 43112, 42957, 42802, 42648, 
+-	42494, 42341, 42189, 42037, 41885, 41734, 41584, 41434, 
+-	41285, 41136, 40988, 40840, 40693, 40546, 40400, 40254, 
+-	40109, 39965, 39821, 39677, 39534, 39392, 39250, 39108, 
+-	38967, 38827, 38687, 38548, 38409, 38270, 38132, 37995, 
+-	37858, 37722, 37586, 37450, 37315, 37181, 37047, 36913, 
+-	36780, 36648, 36516, 36384, 36253, 36122, 35992, 35862, 
+-	35733, 35604, 35476, 35348, 35221, 35094, 34968, 34842, 
+-	34716, 34591, 34466, 34342, 34218, 34095, 33972, 33850, 
+-	33728, 33606, 33485, 33364, 33244, 33124, 33005, 32886, 
+-	32768, 32649, 32532, 32415, 32298, 32181, 32065, 31950, 
+-	31835, 31720, 31606, 31492, 31378, 31265, 31152, 31040, 
+-	30928, 30817, 30706, 30595, 30485, 30375, 30266, 30157, 
+-	30048, 29940, 29832, 29724, 29617, 29510, 29404, 29298, 
+-	29192, 29087, 28982, 28878, 28774, 28670, 28567, 28464, 
+-	28361, 28259, 28157, 28056, 27955, 27854, 27754, 27654, 
+-	27554, 27455, 27356, 27257, 27159, 27061, 26964, 26866, 
+-	26770, 26673, 26577, 26481, 26386, 26291, 26196, 26102, 
+-};
+-
+-
+-int SpectrumSinusTable[256*2] = 
+-{
+-	0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11, 
+-	12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 
+-	24, 25, 25, 26, 27, 28, 28, 29, 30, 30, 31, 32, 32, 33, 34, 34, 
+-	35, 36, 36, 37, 38, 38, 39, 39, 40, 41, 41, 42, 42, 43, 44, 44, 
+-	45, 45, 46, 46, 47, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 
+-	53, 53, 53, 54, 54, 55, 55, 55, 56, 56, 57, 57, 57, 58, 58, 58, 
+-	59, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 61, 61, 62, 62, 62, 
+-	62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 
+-	63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 62, 62, 
+-	62, 62, 62, 62, 61, 61, 61, 61, 61, 60, 60, 60, 60, 59, 59, 59, 
+-	59, 58, 58, 58, 57, 57, 57, 56, 56, 55, 55, 55, 54, 54, 53, 53, 
+-	53, 52, 52, 51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45, 
+-	45, 44, 44, 43, 42, 42, 41, 41, 40, 39, 39, 38, 38, 37, 36, 36, 
+-	35, 34, 34, 33, 32, 32, 31, 30, 30, 29, 28, 28, 27, 26, 25, 25, 
+-	24, 23, 22, 22, 21, 20, 20, 19, 18, 17, 17, 16, 15, 14, 14, 13, 
+-	12, 11, 10, 10, 9, 8, 7, 7, 6, 5, 4, 3, 3, 2, 1, 0, 
+-	0, -1, -1, -2, -3, -3, -4, -5, -6, -7, -7, -8, -9, -10, -10, -11, 
+-	-12, -13, -14, -14, -15, -16, -17, -17, -18, -19, -20, -20, -21, -22, -22, -23, 
+-	-24, -25, -25, -26, -27, -28, -28, -29, -30, -30, -31, -32, -32, -33, -34, -34, 
+-	-35, -36, -36, -37, -38, -38, -39, -39, -40, -41, -41, -42, -42, -43, -44, -44, 
+-	-45, -45, -46, -46, -47, -47, -48, -48, -49, -49, -50, -50, -51, -51, -52, -52, 
+-	-53, -53, -53, -54, -54, -55, -55, -55, -56, -56, -57, -57, -57, -58, -58, -58, 
+-	-59, -59, -59, -59, -60, -60, -60, -60, -61, -61, -61, -61, -61, -62, -62, -62, 
+-	-62, -62, -62, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, 
+-	-63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -62, -62, 
+-	-62, -62, -62, -62, -61, -61, -61, -61, -61, -60, -60, -60, -60, -59, -59, -59, 
+-	-59, -58, -58, -58, -57, -57, -57, -56, -56, -55, -55, -55, -54, -54, -53, -53, 
+-	-53, -52, -52, -51, -51, -50, -50, -49, -49, -48, -48, -47, -47, -46, -46, -45, 
+-	-45, -44, -44, -43, -42, -42, -41, -41, -40, -39, -39, -38, -38, -37, -36, -36, 
+-	-35, -34, -34, -33, -32, -32, -31, -30, -30, -29, -28, -28, -27, -26, -25, -25, 
+-	-24, -23, -22, -22, -21, -20, -20, -19, -18, -17, -17, -16, -15, -14, -14, -13, 
+-	-12, -11, -10, -10, -9, -8, -7, -7, -6, -5, -4, -3, -3, -2, -1, 0, 
+-};
+-
diff --git a/audacious-plugins.spec b/audacious-plugins.spec
index a29523f..ed16ee3 100644
--- a/audacious-plugins.spec
+++ b/audacious-plugins.spec
@@ -10,7 +10,7 @@ Requires: audacious >= %{aud_ver}
 
 Name: audacious-plugins
 Version: 2.5.4
-Release: 1%{?dist}
+Release: 2%{?dist}
 Summary: Plugins for the Audacious audio player
 Group: Applications/Multimedia
 URL: http://audacious-media-player.org/
@@ -33,9 +33,13 @@ Patch1: audacious-plugins-2.4-libdir.patch
 Patch4: audacious-plugins-2.5.4-streambrowser.patch
 #
 Patch5: audacious-plugins-2.5.3-moodbar.patch
+#
+Patch6: audacious-plugins-2.5.4-libmodplug-system.patch
+
+BuildRequires: autoconf
 
 BuildRequires: audacious-devel >= %{aud_ver}
-BuildRequires: gettext
+BuildRequires: gettext-devel
 BuildRequires: desktop-file-utils
 BuildRequires: jack-audio-connection-kit-devel
 BuildRequires: libsamplerate-devel
@@ -159,6 +163,8 @@ providers may build it with libsidplay 2 instead.
 %patch1 -p1 -b .libdir
 %patch4 -p1 -b .streambrowser
 %patch5 -p1 -b .moodbar
+%patch6 -p1 -b .libmodplug-system
+autoreconf -I m4
 
 for i in src/ladspa/ladspa.c
 do
@@ -273,6 +279,9 @@ update-desktop-database &> /dev/null || :
 
 
 %changelog
+* Thu Sep  8 2011 Michael Schwendt <mschwendt at fedoraproject.org> - 2.5.4-2
+- Patch to use system's libmodplug (BR libmodplug-devel).
+
 * Fri Jul 15 2011 Michael Schwendt <mschwendt at fedoraproject.org> - 2.5.4-1
 - Update to 2.5.4 (merged patches, minor fixes, 8k diff).
 


More information about the scm-commits mailing list