diff src/modplug/sndfile.h @ 2337:107c1fed3d92

Port Schism modplug core.
author "Tony Vroon <chainsaw@gentoo.org>"
date Thu, 24 Jan 2008 12:05:59 +0000
parents 6907fc39b53f
children 6a92c4f14338
line wrap: on
line diff
--- a/src/modplug/sndfile.h	Wed Jan 23 19:37:05 2008 +0100
+++ b/src/modplug/sndfile.h	Thu Jan 24 12:05:59 2008 +0000
@@ -5,11 +5,14 @@
  *          Adam Goode       <adam@evdebs.org> (endian and char fixes for PPC)
 */
 
-#include "config.h"
+#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
@@ -28,7 +31,7 @@
 #ifdef MODPLUG_FASTSOUNDLIB
 #define MAX_CHANNELS		80
 #else
-#define MAX_CHANNELS		128
+#define MAX_CHANNELS		256
 #endif
 #define MAX_BASECHANNELS	64
 #define MAX_ENVPOINTS		32
@@ -65,7 +68,6 @@
 #define MOD_TYPE_MT2		0x100000
 #define MOD_TYPE_AMF0		0x200000
 #define MOD_TYPE_PSM		0x400000
-#define MOD_TYPE_J2B		0x800000
 #define MOD_TYPE_UMX		0x80000000 // Fake type
 #define MAX_MODTYPE		23
 
@@ -102,6 +104,8 @@
 #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
@@ -118,6 +122,7 @@
 #define ENV_VOLCARRY		0x0800
 #define ENV_PANCARRY		0x1000
 #define ENV_PITCHCARRY		0x2000
+#define ENV_MUTE		0x4000
 
 #define CMD_NONE                        0
 #define CMD_ARPEGGIO			1
@@ -254,6 +259,9 @@
 #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
@@ -272,7 +280,10 @@
 #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 {
@@ -302,66 +313,59 @@
 	UINT nSustainStart, nSustainEnd;
 	signed char *pSample;
 	UINT nC4Speed;
-	WORD nPan;
-	WORD nVolume;
-	WORD nGlobalVol;
-	WORD uFlags;
-	signed char RelativeTone;
-	signed char nFineTune;
-	BYTE nVibType;
-	BYTE nVibSweep;
-	BYTE nVibDepth;
-	BYTE nVibRate;
+	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;
-	WORD nGlobalVol;
-	WORD nPan;
-	WORD VolPoints[MAX_ENVPOINTS];
-	WORD PanPoints[MAX_ENVPOINTS];
-	WORD PitchPoints[MAX_ENVPOINTS];
-	BYTE VolEnv[MAX_ENVPOINTS];
-	BYTE PanEnv[MAX_ENVPOINTS];
-	BYTE PitchEnv[MAX_ENVPOINTS];
-	BYTE Keyboard[128];
-	BYTE NoteMap[128];
-
-	BYTE nVolEnv;
-	BYTE nPanEnv;
-	BYTE nPitchEnv;
-	BYTE nVolLoopStart;
-	BYTE nVolLoopEnd;
-	BYTE nVolSustainBegin;
-	BYTE nVolSustainEnd;
-	BYTE nPanLoopStart;
-	BYTE nPanLoopEnd;
-	BYTE nPanSustainBegin;
-	BYTE nPanSustainEnd;
-	BYTE nPitchLoopStart;
-	BYTE nPitchLoopEnd;
-	BYTE nPitchSustainBegin;
-	BYTE nPitchSustainEnd;
-	BYTE nNNA;
-	BYTE nDCT;
-	BYTE nDNA;
-	BYTE nPanSwing;
-	BYTE nVolSwing;
-	BYTE nIFC;
-	BYTE nIFR;
-	WORD wMidiBank;
-	BYTE nMidiProgram;
-	BYTE nMidiChannel;
-	BYTE nMidiDrumKey;
-	signed char nPPS;
-	unsigned char nPPC;
+	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;
 
 
@@ -372,6 +376,7 @@
 	signed char * pCurrentSample;
 	DWORD nPos;
 	DWORD nPosLo;	// actually 16-bit
+	unsigned int topnote_offset;
 	LONG nInc;		// 16.16
 	LONG nRightVol;
 	LONG nLeftVol;
@@ -384,8 +389,10 @@
 	DWORD nLoopEnd;
 	LONG nRampRightVol;
 	LONG nRampLeftVol;
-	LONG nFilter_Y1, nFilter_Y2, nFilter_Y3, nFilter_Y4;
-	LONG nFilter_A0, nFilter_B0, nFilter_B1;
+
+	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
@@ -393,37 +400,42 @@
 	LONG nNewRightVol, nNewLeftVol;
 	LONG nRealVolume, nRealPan;
 	LONG nVolume, nPan, nFadeOutVol;
-	LONG nPeriod, nC4Speed, nPortamentoDest;
+	LONG nPeriod, nC4Speed, sample_freq, nPortamentoDest;
 	INSTRUMENTHEADER *pHeader;
 	MODINSTRUMENT *pInstrument;
-	DWORD nVolEnvPosition, nPanEnvPosition, nPitchEnvPosition;
+	int nVolEnvPosition, nPanEnvPosition, nPitchEnvPosition;
 	DWORD nMasterChn, nVUMeter;
 	LONG nGlobalVol, nInsVol;
 	LONG nFineTune, nTranspose;
 	LONG nPortamentoSlide, nAutoVibDepth;
 	UINT nAutoVibPos, nVibratoPos, nTremoloPos, nPanbrelloPos;
 	// 16-bit members
-	signed short nVolSwing, nPanSwing;
-	// 8-bit members
-	BYTE nNote, nNNA;
-	BYTE nNewNote, nNewIns, nCommand, nArpeggio;
-	BYTE nOldVolumeSlide, nOldFineVolUpDown;
-	BYTE nOldPortaUpDown, nOldFinePortaUpDown;
-	BYTE nOldPanSlide, nOldChnVolSlide;
-	BYTE nVibratoType, nVibratoSpeed, nVibratoDepth;
-	BYTE nTremoloType, nTremoloSpeed, nTremoloDepth;
-	BYTE nPanbrelloType, nPanbrelloSpeed, nPanbrelloDepth;
-	BYTE nOldCmdEx, nOldVolParam, nOldTempo;
-	BYTE nOldOffset, nOldHiOffset;
-	BYTE nCutOff, nResonance;
-	BYTE nRetrigCount, nRetrigParam;
-	BYTE nTremorCount, nTremorParam;
-	BYTE nPatternLoop, nPatternLoopCount;
-	BYTE nRowNote, nRowInstr;
-	BYTE nRowVolCmd, nRowVolume;
-	BYTE nRowCommand, nRowParam;
-	BYTE nLeftVU, nRightVU;
-	BYTE nActiveMacro, nPadding;
+	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;
 
 
@@ -454,12 +466,13 @@
 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 long nSamples) = 0;
-	virtual void Init(unsigned long nFreq, int bReset) = 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;
 };
@@ -523,7 +536,7 @@
 } MODMIDICFG, *LPMODMIDICFG;
 
 
-typedef VOID (* LPSNDMIXHOOKPROC)(int *, unsigned long, unsigned long); // buffer, samples, channels
+typedef VOID (* LPSNDMIXHOOKPROC)(int *, unsigned int, unsigned int); // buffer, samples, channels
 
 
 
@@ -535,11 +548,11 @@
 	static UINT m_nXBassDepth, m_nXBassRange;
 	static UINT m_nReverbDepth, m_nReverbDelay, gnReverbType;
 	static UINT m_nProLogicDepth, m_nProLogicDelay;
-	static UINT m_nStereoSeparation;
 	static UINT m_nMaxMixChannels;
 	static LONG m_nStreamVolume;
 	static DWORD gdwSysInfo, gdwSoundSetup, gdwMixingFreq, gnBitsPerSample, gnChannels;
-	static UINT gnAGC, gnVolumeRampSamples, gnVUMeter, gnCPUUsage;
+	static UINT gnAGC, gnVolumeRampSamples, gnCPUUsage;
+	static UINT gnVULeft, gnVURight;
 	static LPSNDMIXHOOKPROC gpSndMixHook;
 	static PMIXPLUGINCREATEPROC gpMixPluginCreateProc;
 
@@ -551,22 +564,24 @@
 	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_nRestartPos;
+	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;
-	UINT m_nMaxOrderPosition;
+	BYTE m_rowHighlightMajor, m_rowHighlightMinor;
 	UINT m_nPatternNames;
 	LPSTR m_lpszSongComments, m_lpszPatternNames;
 	char m_szNames[MAX_INSTRUMENTS][32];    // changed from CHAR
@@ -579,6 +594,7 @@
 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; }
@@ -635,14 +651,7 @@
 	BOOL ReadPSM(LPCBYTE lpStream, DWORD dwMemLength);
 	BOOL ReadJ2B(LPCBYTE lpStream, DWORD dwMemLength);
 	BOOL ReadUMX(LPCBYTE lpStream, DWORD dwMemLength);
-	// Save Functions
-#ifndef MODPLUG_NO_FILESAVE
-	UINT WriteSample(FILE *f, MODINSTRUMENT *pins, UINT nFlags, UINT nMaxLen=0);
-	BOOL SaveXM(LPCSTR lpszFileName, UINT nPacking=0);
-	BOOL SaveS3M(LPCSTR lpszFileName, UINT nPacking=0);
-	BOOL SaveMod(LPCSTR lpszFileName, UINT nPacking=0);
-	BOOL SaveIT(LPCSTR lpszFileName, UINT nPacking=0);
-#endif // MODPLUG_NO_FILESAVE
+	BOOL ReadMID(LPCBYTE lpStream, DWORD dwMemLength);
 	// MOD Convert function
 	UINT GetBestSaveFormat() const;
 	UINT GetSaveFormats() const;
@@ -650,6 +659,10 @@
 	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
@@ -678,6 +691,23 @@
 	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
@@ -694,9 +724,9 @@
 	BOOL ReadNote();
 	BOOL ProcessRow();
 	BOOL ProcessEffects();
-	UINT GetNNAChannel(UINT nChn) const;
+	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);
+	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);
@@ -722,8 +752,10 @@
 	void ExtendedMODCommands(UINT nChn, UINT param);
 	void ExtendedS3MCommands(UINT nChn, UINT param);
 	void ExtendedChannelEffect(MODCHANNEL *, UINT param);
-	void ProcessMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param=0);
-	void SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier=256) const;
+	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
@@ -751,6 +783,7 @@
 	// 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; }
@@ -759,9 +792,7 @@
 	BOOL ITInstrToMPT(const void *p, INSTRUMENTHEADER *penv, UINT trkvers);
 	UINT SaveMixPlugins(FILE *f=NULL, BOOL bUpdate=TRUE);
 	UINT LoadMixPlugins(const void *pData, UINT nLen);
-#ifndef NO_FILTER
-	DWORD CutOffToFrequency(UINT nCutOff, int flt_modifier=256) const; // [0-255] => [1-10KHz]
-#endif
+	void ResetTimestamps(); // for note playback dots
 
 	// Static helper functions
 public:
@@ -909,8 +940,8 @@
 
 #define MIXBUFFERSIZE		512
 #define MIXING_ATTENUATION	4
-#define MIXING_CLIPMIN		(-0x08000000)
-#define MIXING_CLIPMAX		(0x07FFFFFF)
+#define MIXING_CLIPMIN		(-0x04000000)
+#define MIXING_CLIPMAX		(0x03FFFFFF)
 #define VOLUMERAMPPRECISION	12
 #define FADESONGDELAY		100
 #define EQ_BUFFERSIZE		(MIXBUFFERSIZE)
@@ -929,8 +960,18 @@
 #define MOD2XMFineTune(k)	((int)( (signed char)((k)<<4) ))
 #define XM2MODFineTune(k)	((int)( (k>>4)&0x0f ))
 
-int _muldiv(long a, long b, long c);
-int _muldivr(long a, long b, long c);
+// 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