/* * This source code is public domain. * * Authors: Olivier Lapicque , * Adam Goode (endian and char fixes for PPC) */ #ifndef __SNDFILE_H #define __SNDFILE_H #ifndef LPCBYTE typedef const BYTE * LPCBYTE; #endif #define MOD_AMIGAC2 0x1AB #define MAX_SAMPLE_LENGTH 16000000 #define MAX_SAMPLE_RATE 50000 #define MAX_ORDERS 256 #define MAX_PATTERNS 240 #define MAX_SAMPLES 240 #define MAX_INSTRUMENTS MAX_SAMPLES #ifdef FASTSOUNDLIB #define MAX_CHANNELS 80 #else #define MAX_CHANNELS 128 #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_J2B 0x800000 #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 #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 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 /* 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 */ /* 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; WORD nPan; WORD nVolume; WORD nGlobalVol; WORD uFlags; signed char RelativeTone; signed char nFineTune; BYTE nVibType; BYTE nVibSweep; BYTE nVibDepth; BYTE nVibRate; CHAR name[22]; } MODINSTRUMENT; /* 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; CHAR name[32]; CHAR filename[12]; } 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 */ 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; LONG nFilter_Y1, nFilter_Y2, nFilter_Y3, nFilter_Y4; LONG 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, nPortamentoDest; INSTRUMENTHEADER *pHeader; MODINSTRUMENT *pInstrument; DWORD 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; } 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 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 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 long, unsigned long); /* 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_nStereoSeparation; static UINT m_nMaxMixChannels; static LONG m_nStreamVolume; static DWORD gdwSysInfo, gdwSoundSetup, gdwMixingFreq, gnBitsPerSample, gnChannels; static UINT gnAGC, gnVolumeRampSamples, gnVUMeter, gnCPUUsage; 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 */ 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_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_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; 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 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 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 */ /* 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: /* 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); /*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) const; void CheckNNA(UINT nChn, UINT instr, int note, BOOL bForceCut); void NoteChange(UINT nChn, int note, BOOL bPorta=FALSE, BOOL bResetEnv=TRUE); 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 ProcessMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param=0); void SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier=256) 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 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); #ifndef NO_FILTER DWORD CutOffToFrequency(UINT nCutOff, int flt_modifier=256) const; /* [0-255] => [1-10KHz] */ #endif /* 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 (-0x08000000) #define MIXING_CLIPMAX (0x07FFFFFF) #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 )) int _muldiv(long a, long b, long c); int _muldivr(long a, long b, long 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 /* From libsdl */ #ifdef 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