changeset 2546:a4c855226874

Automated merge with ssh://hg.atheme.org//hg/audacious-plugins
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 30 Apr 2008 13:29:56 +0300
parents 585f2fc4134e (diff) 7591d7534eb8 (current diff)
children d3432c34e817 6d17b2c838df
files m4/libmikmod.m4
diffstat 5 files changed, 3 insertions(+), 1130 deletions(-) [+]
line wrap: on
line diff
--- a/src/modplug/Makefile	Mon Apr 28 18:24:46 2008 +0300
+++ b/src/modplug/Makefile	Wed Apr 30 13:29:56 2008 +0300
@@ -22,7 +22,6 @@
        load_mtm.cxx		\
        load_mod.cxx		\
        load_med.cxx		\
-       load_mid.cxx		\
        load_mdl.cxx		\
        load_it.cxx		\
        load_far.cxx		\
--- a/src/modplug/load_mid.cxx	Mon Apr 28 18:24:46 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1126 +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@jps.net>
-*/
-
-//////////////////////////////////////////////
-// MIDI loader                              //
-//////////////////////////////////////////////
-#include "stdafx.h"
-#include "sndfile.h"
-
-#define MIDI_DRUMCHANNEL	10
-#define MIDI_MAXTRACKS		64
-
-UINT gnMidiImportSpeed = 3;
-UINT gnMidiPatternLen = 128;
-
-#pragma pack(1)
-
-typedef struct MIDIFILEHEADER
-{
-	CHAR id[4];		// "MThd" = 0x6468544D
-	DWORD len;		// 6
-	WORD w1;		// 1?
-	WORD wTrks;		// 2?
-	WORD wDivision;	// F0
-} MIDIFILEHEADER;
-
-
-typedef struct MIDITRACKHEADER
-{
-	CHAR id[4];	// "MTrk" = 0x6B72544D
-	DWORD len;
-} MIDITRACKHEADER;
-
-static LONG midivolumetolinear(UINT nMidiVolume)
-{
-	return (nMidiVolume * nMidiVolume << 16) / (127*127);
-}
-
-//////////////////////////////////////////////////////////////////////
-// Midi Loader Internal Structures
-
-#define CHNSTATE_NOTEOFFPENDING		0x0001
-
-// MOD Channel State description (current volume, panning, etc...)
-typedef struct MODCHANNELSTATE
-{
-	DWORD flags;	// Channel Flags
-	WORD idlecount;
-	WORD pitchsrc, pitchdest;	// Pitch Bend (current position/new position)
-	BYTE parent;	// Midi Channel parent
-	BYTE pan;		// Channel Panning			0-255
-	BYTE note;		// Note On # (0=available)
-} MODCHANNELSTATE;
-
-// MIDI Channel State (Midi Channels 0-15)
-typedef struct MIDICHANNELSTATE
-{
-	DWORD flags;		// Channel Flags
-	WORD pitchbend;		// Pitch Bend Amount (14-bits unsigned)
-	BYTE note_on[128];	// If note=on -> MOD channel # + 1 (0 if note=off)
-	BYTE program;		// Channel Midi Program
-	WORD bank;			// 0-16383
-	// -- Controllers --------- function ---------- CC# --- range  --- init (midi) ---
-	BYTE pan;			// Channel Panning			CC10	[0-255]		128 (64)
-	BYTE expression;	// Channel Expression		CC11	0-128		128	(127)
-	BYTE volume;		// Channel Volume			CC7		0-128		80	(100)
-	BYTE modulation;	// Modulation				CC1		0-127		0
-	BYTE pitchbendrange;// Pitch Bend Range								64
-} MIDICHANNELSTATE;
-
-typedef struct MIDITRACK
-{
-	LPCBYTE ptracks, ptrmax;
-	DWORD status;
-	LONG nexteventtime;
-} MIDITRACK;
-
-#pragma pack()
-
-
-
-LPCSTR szMidiGroupNames[17] =
-{
-	"Piano",
-	"Chromatic Percussion",
-	"Organ",
-	"Guitar",
-	"Bass",
-	"Strings",
-	"Ensemble",
-	"Brass",
-	"Reed",
-	"Pipe",
-	"Synth Lead",
-	"Synth Pad",
-	"Synth Effects",
-	"Ethnic",
-	"Percussive",
-	"Sound Effects",
-	"Percussions"
-};
-
-
-LPCSTR szMidiProgramNames[128] =
-{
-	// 1-8: Piano
-	"Acoustic Grand Piano",
-	"Bright Acoustic Piano",
-	"Electric Grand Piano",
-	"Honky-tonk Piano",
-	"Electric Piano 1",
-	"Electric Piano 2",
-	"Harpsichord",
-	"Clavi",
-	// 9-16: Chromatic Percussion
-	"Celesta",
-	"Glockenspiel",
-	"Music Box",
-	"Vibraphone",
-	"Marimba",
-	"Xylophone",
-	"Tubular Bells",
-	"Dulcimer",
-	// 17-24: Organ
-	"Drawbar Organ",
-	"Percussive Organ",
-	"Rock Organ",
-	"Church Organ",
-	"Reed Organ",
-	"Accordion",
-	"Harmonica",
-	"Tango Accordion",
-	// 25-32: Guitar
-	"Acoustic Guitar (nylon)",
-	"Acoustic Guitar (steel)",
-	"Electric Guitar (jazz)",
-	"Electric Guitar (clean)",
-	"Electric Guitar (muted)",
-	"Overdriven Guitar",
-	"Distortion Guitar",
-	"Guitar harmonics",
-	// 33-40   Bass
-	"Acoustic Bass",
-	"Electric Bass (finger)",
-	"Electric Bass (pick)",
-	"Fretless Bass",
-	"Slap Bass 1",
-	"Slap Bass 2",
-	"Synth Bass 1",
-	"Synth Bass 2",
-	// 41-48   Strings
-	"Violin",
-	"Viola",
-	"Cello",
-	"Contrabass",
-	"Tremolo Strings",
-	"Pizzicato Strings",
-	"Orchestral Harp",
-	"Timpani",
-	// 49-56   Ensemble
-	"String Ensemble 1",
-	"String Ensemble 2",
-	"SynthStrings 1",
-	"SynthStrings 2",
-	"Choir Aahs",
-	"Voice Oohs",
-	"Synth Voice",
-	"Orchestra Hit",
-	// 57-64   Brass
-	"Trumpet",
-	"Trombone",
-	"Tuba",
-	"Muted Trumpet",
-	"French Horn",
-	"Brass Section",
-	"SynthBrass 1",
-	"SynthBrass 2",
-	// 65-72   Reed
-	"Soprano Sax",
-	"Alto Sax",
-	"Tenor Sax",
-	"Baritone Sax",
-	"Oboe",
-	"English Horn",
-	"Bassoon",
-	"Clarinet",
-	// 73-80   Pipe
-	"Piccolo",
-	"Flute",
-	"Recorder",
-	"Pan Flute",
-	"Blown Bottle",
-	"Shakuhachi",
-	"Whistle",
-	"Ocarina",
-	// 81-88   Synth Lead
-	"Lead 1 (square)",
-	"Lead 2 (sawtooth)",
-	"Lead 3 (calliope)",
-	"Lead 4 (chiff)",
-	"Lead 5 (charang)",
-	"Lead 6 (voice)",
-	"Lead 7 (fifths)",
-	"Lead 8 (bass + lead)",
-	// 89-96   Synth Pad
-	"Pad 1 (new age)",
-	"Pad 2 (warm)",
-	"Pad 3 (polysynth)",
-	"Pad 4 (choir)",
-	"Pad 5 (bowed)",
-	"Pad 6 (metallic)",
-	"Pad 7 (halo)",
-	"Pad 8 (sweep)",
-	// 97-104  Synth Effects
-	"FX 1 (rain)",
-	"FX 2 (soundtrack)",
-	"FX 3 (crystal)",
-	"FX 4 (atmosphere)",
-	"FX 5 (brightness)",
-	"FX 6 (goblins)",
-	"FX 7 (echoes)",
-	"FX 8 (sci-fi)",
-	// 105-112 Ethnic
-	"Sitar",
-	"Banjo",
-	"Shamisen",
-	"Koto",
-	"Kalimba",
-	"Bag pipe",
-	"Fiddle",
-	"Shanai",
-	// 113-120 Percussive
-	"Tinkle Bell",
-	"Agogo",
-	"Steel Drums",
-	"Woodblock",
-	"Taiko Drum",
-	"Melodic Tom",
-	"Synth Drum",
-	"Reverse Cymbal",
-	// 121-128 Sound Effects
-	"Guitar Fret Noise",
-	"Breath Noise",
-	"Seashore",
-	"Bird Tweet",
-	"Telephone Ring",
-	"Helicopter",
-	"Applause",
-	"Gunshot"
-};
-
-
-// Notes 25-85
-LPCSTR szMidiPercussionNames[61] =
-{
-	"Seq Click",
-	"Brush Tap",
-	"Brush Swirl",
-	"Brush Slap",
-	"Brush Swirl W/Attack",
-	"Snare Roll",
-	"Castanet",
-	"Snare Lo",
-	"Sticks",
-	"Bass Drum Lo",
-	"Open Rim Shot",
-	"Acoustic Bass Drum",
-	"Bass Drum 1",
-	"Side Stick",
-	"Acoustic Snare",
-	"Hand Clap",
-	"Electric Snare",
-	"Low Floor Tom",
-	"Closed Hi Hat",
-	"High Floor Tom",
-	"Pedal Hi-Hat",
-	"Low Tom",
-	"Open Hi-Hat",
-	"Low-Mid Tom",
-	"Hi Mid Tom",
-	"Crash Cymbal 1",
-	"High Tom",
-	"Ride Cymbal 1",
-	"Chinese Cymbal",
-	"Ride Bell",
-	"Tambourine",
-	"Splash Cymbal",
-	"Cowbell",
-	"Crash Cymbal 2",
-	"Vibraslap",
-	"Ride Cymbal 2",
-	"Hi Bongo",
-	"Low Bongo",
-	"Mute Hi Conga",
-	"Open Hi Conga",
-	"Low Conga",
-	"High Timbale",
-	"Low Timbale",
-	"High Agogo",
-	"Low Agogo",
-	"Cabasa",
-	"Maracas",
-	"Short Whistle",
-	"Long Whistle",
-	"Short Guiro",
-	"Long Guiro",
-	"Claves",
-	"Hi Wood Block",
-	"Low Wood Block",
-	"Mute Cuica",
-	"Open Cuica",
-	"Mute Triangle",
-	"Open Triangle",
-	"Shaker",
-	"Jingle Bell",
-	"Bell Tree",
-};
-
-
-const WORD kMidiChannelPriority[16] =
-{
-	0xFFFE, 0xFFFC, 0xFFF8, 0xFFF0,	0xFFE0, 0xFFC0, 0xFF80, 0xFF00,
-	0xFE00, 0xFDFF, 0xF800, 0xF000,	0xE000, 0xC000, 0x8000, 0x0000,
-};
-
-
-///////////////////////////////////////////////////////////////////////////
-// Helper functions
-
-static LONG getmidilong(LPCBYTE &p, LPCBYTE pmax)
-//----------------------------------------------------------
-{
-	DWORD n;
-	UINT a;
-
-	a = (p < pmax) ? *(p++) : 0;
-	n = 0;
-	while (a&0x80)
-	{
-		n = (n<<7)|(a&0x7F);
-		a = (p < pmax) ? *(p++) : 0;
-	}
-	return (n<<7)|(LONG)a;
-}
-
-
-// Returns MOD tempo and tick multiplier
-static int ConvertMidiTempo(int tempo_us, int *pTickMultiplier)
-//-------------------------------------------------------------
-{
-	int nBestModTempo = 120;
-	int nBestError = 1000000; // 1s
-	int nBestMultiplier = 1;
-	int nSpeed = gnMidiImportSpeed;
-	for (int nModTempo=110; nModTempo<=240; nModTempo++)
-	{
-		int tick_us = (2500000) / nModTempo;
-		int nFactor = (tick_us+tempo_us/2) / tempo_us;
-		if (!nFactor) nFactor = 1;
-		int nError = tick_us - tempo_us * nFactor;
-		if (nError < 0) nError = -nError;
-		if (nError < nBestError)
-		{
-			nBestError = nError;
-			nBestModTempo = nModTempo;
-			nBestMultiplier = nFactor;
-		}
-		if ((!nError) || ((nError<=1) && (nFactor==64))) break;
-	}
-	*pTickMultiplier = nBestMultiplier * nSpeed;
-	return nBestModTempo;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Maps a midi instrument - returns the instrument number in the file
-UINT CSoundFile::MapMidiInstrument(DWORD dwBankProgram, UINT nChannel, UINT nNote)
-//--------------------------------------------------------------------------------
-{
-	INSTRUMENTHEADER *penv;
-	UINT nProgram = dwBankProgram & 0x7F;
-	UINT nBank = dwBankProgram >> 7;
-
-	nNote &= 0x7F;
-	if (nNote >= 120) return 0;
-	for (UINT i=1; i<=m_nInstruments; i++) if (Headers[i])
-	{
-		INSTRUMENTHEADER *p = Headers[i];
-		// Drum Kit ?
-		if (nChannel == MIDI_DRUMCHANNEL)
-		{
-			if (nNote == p->nMidiDrumKey) return i;
-		} else
-		// Melodic Instrument
-		{
-			if (nProgram == p->nMidiProgram) return i;
-		}
-	}
-	if ((m_nInstruments + 1 >= MAX_INSTRUMENTS) || (m_nSamples + 1 >= MAX_SAMPLES)) return 0;
-	penv = new INSTRUMENTHEADER;
-	if (!penv) return 0;
-	memset(penv, 0, sizeof(INSTRUMENTHEADER));
-	m_nSamples++;
-	m_nInstruments++;
-	Headers[m_nInstruments] = penv;
-	penv->wMidiBank = nBank;
-	penv->nMidiProgram = nProgram;
-	penv->nMidiChannel = nChannel;
-	if (nChannel == MIDI_DRUMCHANNEL) penv->nMidiDrumKey = nNote;
-	penv->nGlobalVol = 128;
-	penv->nFadeOut = 1024;
-	penv->nPan = 128;
-	penv->nPPC = 5*12;
-	penv->nNNA = NNA_NOTEOFF;
-	penv->nDCT = (nChannel == MIDI_DRUMCHANNEL) ? DCT_SAMPLE : DCT_NOTE;
-	penv->nDNA = DNA_NOTEFADE;
-	for (UINT j=0; j<120; j++)
-	{
-		int mapnote = j+1;
-		if (nChannel == MIDI_DRUMCHANNEL)
-		{
-			mapnote = 61;
-			/*mapnote = 61 + j - nNote;
-			if (mapnote < 1) mapnote = 1;
-			if (mapnote > 120) mapnote = 120;*/
-		}
-		penv->Keyboard[j] = m_nSamples;
-		penv->NoteMap[j] = (BYTE)mapnote;
-	}
-	penv->dwFlags |= ENV_VOLUME;
-	if (nChannel != MIDI_DRUMCHANNEL) penv->dwFlags |= ENV_VOLSUSTAIN;
-	penv->VolEnv.nNodes=4;
-	penv->VolEnv.Ticks[0]=0;
-	penv->VolEnv.Values[0] = 64;
-	penv->VolEnv.Ticks[1] = 10;
-	penv->VolEnv.Values[1] = 64;
-	penv->VolEnv.Ticks[2] = 15;
-	penv->VolEnv.Values[2] = 48;
-	penv->VolEnv.Ticks[3] = 20;
-	penv->VolEnv.Values[3] = 0;
-	penv->VolEnv.nSustainStart=1;
-	penv->VolEnv.nSustainEnd=1;
-	// Sample
-	Ins[m_nSamples].nPan = 128;
-	Ins[m_nSamples].nVolume = 256;
-	Ins[m_nSamples].nGlobalVol = 64;
-	if (nChannel != MIDI_DRUMCHANNEL)
-	{
-		// GM Midi Name
-		strcpy((char*)penv->name, (char*)szMidiProgramNames[nProgram]);
-		strcpy((char*)m_szNames[m_nSamples], (char*)szMidiProgramNames[nProgram]);
-	} else
-	{
-		strcpy((char*)penv->name, "Percussions");
-		if ((nNote >= 24) && (nNote <= 84))
-			strcpy((char*)m_szNames[m_nSamples], (char*)szMidiPercussionNames[nNote-24]);
-		else
-			strcpy((char*)m_szNames[m_nSamples], "Percussions");
-	}
-	return m_nInstruments;
-}
-
-
-/////////////////////////////////////////////////////////////////
-// Loader Status
-#define MIDIGLOBAL_SONGENDED		0x0001
-#define MIDIGLOBAL_FROZEN			0x0002
-#define MIDIGLOBAL_UPDATETEMPO		0x0004
-#define MIDIGLOBAL_UPDATEMASTERVOL	0x0008
-// Midi Globals
-#define MIDIGLOBAL_GMSYSTEMON		0x0100
-#define MIDIGLOBAL_XGSYSTEMON		0x0200
-
-
-BOOL CSoundFile::ReadMID(const BYTE *lpStream, DWORD dwMemLength)
-//---------------------------------------------------------------
-{
-	const MIDIFILEHEADER *pmfh = (const MIDIFILEHEADER *)lpStream;
-	const MIDITRACKHEADER *pmth;
-	MODCHANNELSTATE chnstate[MAX_BASECHANNELS];
-	MIDICHANNELSTATE midichstate[16];
-	MIDITRACK miditracks[MIDI_MAXTRACKS];
-	DWORD dwMemPos, dwGlobalFlags, tracks, tempo;
-	UINT row, pat, midimastervol;
-	short int division;
-	int midi_clock, nTempoUsec, nPPQN, nTickMultiplier;
-
-	// Fix import parameters
-	if (gnMidiImportSpeed < 2) gnMidiImportSpeed = 2;
-	if (gnMidiImportSpeed > 6) gnMidiImportSpeed = 6;
-	if (gnMidiPatternLen < 64) gnMidiPatternLen = 64;
-	if (gnMidiPatternLen > 256) gnMidiPatternLen = 256;
-	// Detect RMI files
-	if ((dwMemLength > 12)
-	 && (memcmp(lpStream, "RIFF",4) == 0)
-	 && (memcmp(lpStream, "RMID",4) == 0))
-	{
-		lpStream += 12;
-		dwMemLength -= 12;
-		while (dwMemLength > 8)
-		{
-			char *id = (char*)lpStream;
-			DWORD len = *(DWORD *)(lpStream+4);
-			lpStream += 8;
-			dwMemLength -= 8;
-			if ((memcmp(id, "data",4) == 0) && (len < dwMemLength))
-			{
-				dwMemLength = len;
-				pmfh = (const MIDIFILEHEADER *)lpStream;
-				break;
-			}
-			if (len >= dwMemLength) return FALSE;
-			lpStream += len;
-			dwMemLength -= len;
-		}
-	}
-	// MIDI File Header
-	if ((dwMemLength < sizeof(MIDIFILEHEADER)+8) || (memcmp(pmfh->id, "MThd",4) != 0)) return FALSE;
-	dwMemPos = 8 + bswapBE32(pmfh->len);
-	if (dwMemPos >= dwMemLength - 8) return FALSE;
-	pmth = (MIDITRACKHEADER *)(lpStream+dwMemPos);
-	tracks = bswapBE16(pmfh->wTrks);
-	if ((!tracks) || (memcmp(pmth->id, "MTrk", 4) != 0)) return FALSE;
-	if (tracks > MIDI_MAXTRACKS) tracks = MIDI_MAXTRACKS;
-	// Reading File...
-	m_nType = MOD_TYPE_MID;
-	m_nChannels = 32;
-	m_nSamples = 0;
-	m_nInstruments = 0;
-	m_dwSongFlags |= (SONG_LINEARSLIDES | SONG_INSTRUMENTMODE);
-	m_szNames[0][0] = 0;
-	// MIDI->MOD Tempo Conversion
-	division = bswapBE16(pmfh->wDivision);
-	if (division < 0)
-	{
-		int nFrames = -(division>>8);
-		int nSubFrames = (division & 0xff);
-		nPPQN = nFrames * nSubFrames / 2;
-		if (!nPPQN) nPPQN = 1;
-	} else
-	{
-		nPPQN = (division) ? division : 96;
-	}
-	nTempoUsec = 500000 / nPPQN;
-	tempo = ConvertMidiTempo(nTempoUsec, &nTickMultiplier);
-	m_nDefaultTempo = tempo;
-	m_nDefaultSpeed = gnMidiImportSpeed;
-	m_nDefaultGlobalVolume = 256;
-	midimastervol = m_nDefaultGlobalVolume;
-	
-	// Initializing 
-	memset(Order, 0xFF, sizeof(Order));
-	memset(chnstate, 0, sizeof(chnstate));
-	memset(miditracks, 0, sizeof(miditracks));
-	memset(midichstate, 0, sizeof(midichstate));
-	// Initializing Patterns
-	Order[0] = 0;
-	for (UINT ipat=0; ipat<MAX_PATTERNS; ipat++) PatternSize[ipat] = gnMidiPatternLen;
-	// Initializing Channels
-	for (UINT ics=0; ics<MAX_BASECHANNELS; ics++)
-	{
-		// Channel settings
-		ChnSettings[ics].nPan = 128;
-		ChnSettings[ics].nVolume = 64;
-		ChnSettings[ics].dwFlags = 0;
-		// Channels state
-		chnstate[ics].pan = 128;
-		chnstate[ics].pitchsrc = 0x2000;
-		chnstate[ics].pitchdest = 0x2000;
-	}
-	// Initializing Track Pointers
-	for (UINT itrk=0; itrk<tracks; itrk++)
-	{
-		miditracks[itrk].nexteventtime = -1;
-		miditracks[itrk].status = 0x2F;
-		pmth = (MIDITRACKHEADER *)(lpStream+dwMemPos);
-		if (dwMemPos + 8 >= dwMemLength) break;
-		DWORD len = bswapBE32(pmth->len);
-		if ((memcmp(pmth->id, "MTrk", 4) == 0) && (dwMemPos + 8 + len <= dwMemLength))
-		{
-			// Initializing midi tracks
-			miditracks[itrk].ptracks = lpStream+dwMemPos+8;
-			miditracks[itrk].ptrmax = miditracks[itrk].ptracks + len;
-			miditracks[itrk].nexteventtime = getmidilong(miditracks[itrk].ptracks, miditracks[itrk].ptrmax);
-		}
-		dwMemPos += 8 + len;
-	}
-	// Initializing midi channels state
-	for (UINT imidi=0; imidi<16; imidi++)
-	{
-		midichstate[imidi].pan = 128;			// middle
-		midichstate[imidi].expression = 128;	// no attenuation
-		midichstate[imidi].volume = 80;			// GM specs defaults to 100
-		midichstate[imidi].pitchbend = 0x2000;	// Pitch Bend Amount
-		midichstate[imidi].pitchbendrange = 64;	// Pitch Bend Range: +/- 2 semitones
-	}
-	////////////////////////////////////////////////////////////////////////////
-	// Main Midi Sequencer Loop
-	pat = 0;
-	row = 0;
-	midi_clock = 0;
-	dwGlobalFlags = MIDIGLOBAL_UPDATETEMPO | MIDIGLOBAL_FROZEN;
-	do
-	{
-		// Allocate current pattern if not allocated yet
-		if (!Patterns[pat])
-		{
-			Patterns[pat] = AllocatePattern(PatternSize[pat], m_nChannels);
-			if (!Patterns[pat]) break;
-		}
-		dwGlobalFlags |= MIDIGLOBAL_SONGENDED;
-		MODCOMMAND *m = Patterns[pat] + row * m_nChannels;
-		// Parse Tracks
-		for (UINT trk=0; trk<tracks; trk++) if (miditracks[trk].ptracks)
-		{
-			MIDITRACK *ptrk = &miditracks[trk];
-			dwGlobalFlags &= ~MIDIGLOBAL_SONGENDED;
-			while ((ptrk->ptracks) && (ptrk->nexteventtime >= 0) && (midi_clock+(nTickMultiplier>>2) >= ptrk->nexteventtime))
-			{
-				if (ptrk->ptracks[0] & 0x80) ptrk->status = *(ptrk->ptracks++);
-				switch(ptrk->status)
-				{
-				/////////////////////////////////////////////////////////////////////
-				// End Of Track
-				case 0x2F:
-				// End Of Song
-				case 0xFC:
-					ptrk->ptracks = NULL;
-					break;
-
-				/////////////////////////////////////////////////////////////////////
-				// SYSEX messages
-				case 0xF0:
-				case 0xF7:
-					{
-						LONG len = getmidilong(ptrk->ptracks, ptrk->ptrmax);
-						if ((len > 1) && (ptrk->ptracks + len <ptrk->ptrmax) && (ptrk->ptracks[len-1] == 0xF7))
-						{
-							DWORD dwSysEx1 = 0, dwSysEx2 = 0;
-							if (len >= 4) dwSysEx1 = (*((DWORD *)(ptrk->ptracks))) & 0x7F7F7F7F;
-							if (len >= 8) dwSysEx2 = (*((DWORD *)(ptrk->ptracks+4))) & 0x7F7F7F7F;
-							// GM System On
-							if ((len == 5) && (dwSysEx1 == 0x01097F7E))
-							{
-								dwGlobalFlags |= MIDIGLOBAL_GMSYSTEMON;
-							} else
-							// XG System On
-							if ((len == 8) && ((dwSysEx1 & 0xFFFFF0FF) == 0x004c1043) && (dwSysEx2 == 0x77007e00))
-							{
-								dwGlobalFlags |= MIDIGLOBAL_XGSYSTEMON;
-							} else
-							// Midi Master Volume
-							if ((len == 7) && (dwSysEx1 == 0x01047F7F))
-							{
-								midimastervol = midivolumetolinear(ptrk->ptracks[5] & 0x7F) >> 8;
-								if (midimastervol < 16) midimastervol = 16;
-								dwGlobalFlags |= MIDIGLOBAL_UPDATEMASTERVOL;
-							}
-						}
-						ptrk->ptracks += len;
-					}
-					break;
-				
-				//////////////////////////////////////////////////////////////////////
-				// META-events: FF.code.len.data[len]
-				case 0xFF:
-					{
-						UINT i = *(ptrk->ptracks++);
-						LONG len = getmidilong(ptrk->ptracks, ptrk->ptrmax);
-						if (ptrk->ptracks+len > ptrk->ptrmax)
-						{
-							// EOF
-							ptrk->ptracks = NULL;
-						} else
-						switch(i)
-						{
-						// FF.01 [text]: Song Information
-						case 0x01:
-							if (!len) break;
-							if ((len < 32) && (!m_szNames[0][0]))
-							{
-								memcpy(m_szNames[0], ptrk->ptracks, len);
-								m_szNames[0][len] = 0;
-							} else
-							if ((!m_lpszSongComments) && (ptrk->ptracks[0]) && (ptrk->ptracks[0] < 0x7F))
-							{
-								m_lpszSongComments = new char [len+1];
-								if (m_lpszSongComments)
-								{
-									memcpy(m_lpszSongComments, ptrk->ptracks, len);
-									m_lpszSongComments[len] = 0;
-								}
-							}
-							break;
-						// FF.02 [text]: Song Copyright
-						case 0x02:
-							if (!len) break;
-							if ((!m_lpszSongComments) && (ptrk->ptracks[0]) && (ptrk->ptracks[0] < 0x7F) && (len > 7))
-							{
-								m_lpszSongComments = new char [len+1];
-								if (m_lpszSongComments)
-								{
-									memcpy(m_lpszSongComments, ptrk->ptracks, len);
-									m_lpszSongComments[len] = 0;
-								}
-							}
-							break;
-						// FF.03: Sequence Name
-						case 0x03:
-						// FF.06: Sequence Text (->Pattern names)
-						case 0x06:
-							if ((len > 1) && (!trk))
-							{
-								UINT k = (len < 32) ? len : 31;
-								CHAR s[32];
-								memcpy(s, ptrk->ptracks, k);
-								s[k] = 0;
-								if ((!strnicmp((char*)s, "Copyri", 6)) || (!s[0])) break;
-								if (i == 0x03)
-								{
-									if (!m_szNames[0][0]) strcpy((char*)m_szNames[0], (char*)s);
-								}
-							}
-							break;
-						// FF.07: Cue Point (marker)
-						// FF.20: Channel Prefix
-						// FF.2F: End of Track
-						case 0x2F:
-							ptrk->status = 0x2F;
-							ptrk->ptracks = NULL;
-							break;
-						// FF.51 [tttttt]: Set Tempo
-						case 0x51:
-							{
-								LONG l = ptrk->ptracks[0];
-								l = (l << 8) | ptrk->ptracks[1];
-								l = (l << 8) | ptrk->ptracks[2];
-								if (l <= 0) break;
-								nTempoUsec = l / nPPQN;
-								if (nTempoUsec < 100) nTempoUsec = 100;
-								tempo = ConvertMidiTempo(nTempoUsec, &nTickMultiplier);
-								dwGlobalFlags |= MIDIGLOBAL_UPDATETEMPO;
-							}
-							break;
-						// FF.58: Time Signature
-						// FF.7F: Sequencer-Specific
-						}
-						if (ptrk->ptracks) ptrk->ptracks += len;
-					}
-					break;
-
-				//////////////////////////////////////////////////////////////////////////
-				// Regular Voice Events
-				default:
-				{
-					UINT midich = (ptrk->status & 0x0F)+1;
-					UINT midist = ptrk->status & 0xF0;
-					MIDICHANNELSTATE *pmidich = &midichstate[midich-1];
-					UINT note, velocity;
-
-					switch(midist)
-					{
-					//////////////////////////////////
-					// Note Off:	80.note.velocity
-					case 0x80:
-					// Note On:		90.note.velocity
-					case 0x90:
-						note = ptrk->ptracks[0] & 0x7F;
-						velocity = (midist == 0x90) ? (ptrk->ptracks[1] & 0x7F) : 0;
-						ptrk->ptracks += 2;
-						// Note On: 90.note.velocity
-						if (velocity)
-						{
-							// Start counting rows
-							dwGlobalFlags &= ~MIDIGLOBAL_FROZEN;
-							// if the note is already playing, we reuse this channel
-							UINT nchn = pmidich->note_on[note];
-							if ((nchn) && (chnstate[nchn-1].parent != midich)) nchn = 0;
-							// or else, we look for an available child channel
-							if (!nchn)
-							{
-								for (UINT i=0; i<m_nChannels; i++) if (chnstate[i].parent == midich)
-								{
-									if ((!chnstate[i].note) && ((!m[i].note) || (m[i].note & 0x80)))
-									{
-										// found an available channel
-										nchn = i+1;
-										break;
-									}
-								}
-							}
-							// still nothing? in this case, we try to allocate a new mod channel
-							if (!nchn)
-							{
-								for (UINT i=0; i<m_nChannels; i++) if (!chnstate[i].parent)
-								{
-									nchn = i+1;
-									chnstate[i].parent = midich;
-									break;
-								}
-							}
-							// still not? we have to steal a voice from another channel
-							// We found our channel: let's do the note on
-							if (nchn)
-							{
-								pmidich->note_on[note] = nchn;
-								nchn--;
-								chnstate[nchn].pitchsrc = pmidich->pitchbend;
-								chnstate[nchn].pitchdest = pmidich->pitchbend;
-								chnstate[nchn].flags &= ~CHNSTATE_NOTEOFFPENDING;
-								chnstate[nchn].idlecount = 0;
-								chnstate[nchn].note = note+1;
-								int realnote = note;
-								if (midich != 10)
-								{
-									realnote += (((int)pmidich->pitchbend - 0x2000) * pmidich->pitchbendrange) / (0x2000*32);
-									if (realnote < 0) realnote = 0;
-									if (realnote > 119) realnote = 119;
-								}
-								m[nchn].note = realnote+1;
-								m[nchn].instr = MapMidiInstrument(pmidich->program + ((UINT)pmidich->bank << 7), midich, note);
-								m[nchn].volcmd = VOLCMD_VOLUME;
-								LONG vol = midivolumetolinear(velocity) >> 8;
-								vol = (vol * (LONG)pmidich->volume * (LONG)pmidich->expression) >> 13;
-								if (vol > 256) vol = 256;
-								if (vol < 4) vol = 4;
-								m[nchn].vol = (BYTE)(vol>>2);
-								// Channel Panning
-								if ((!m[nchn].command) && (pmidich->pan != chnstate[nchn].pan))
-								{
-									chnstate[nchn].pan = pmidich->pan;
-									m[nchn].param = pmidich->pan;
-									m[nchn].command = CMD_PANNING8;
-								}
-							}
-						} else
-						// Note Off; 90.note.00
-						if (!(dwGlobalFlags & MIDIGLOBAL_FROZEN))
-						{
-							UINT nchn = pmidich->note_on[note];
-							if (nchn)
-							{
-								nchn--;
-								chnstate[nchn].flags |= CHNSTATE_NOTEOFFPENDING;
-								chnstate[nchn].note = 0;
-								pmidich->note_on[note] = 0;
-							} else
-							{
-								for (UINT i=0; i<m_nChannels; i++)
-								{
-									if ((chnstate[i].parent == midich) && (chnstate[i].note == note+1))
-									{
-										chnstate[i].note = 0;
-										chnstate[i].flags |= CHNSTATE_NOTEOFFPENDING;
-									}
-								}
-							}
-						}
-						break;
-
-					///////////////////////////////////
-					// A0.xx.yy: Aftertouch
-					case 0xA0:
-						{
-							ptrk->ptracks += 2;
-						}
-						break;
-
-					///////////////////////////////////
-					// B0: Control Change
-					case 0xB0:
-						{
-							UINT controller = ptrk->ptracks[0];
-							UINT value = ptrk->ptracks[1] & 0x7F;
-							ptrk->ptracks += 2;
-							switch(controller)
-							{
-							// Bn.00.xx: Bank Select MSB (GS)
-							case 0x00:
-								pmidich->bank &= 0x7F;
-								pmidich->bank |= (value << 7);
-								break;
-							// Bn.01.xx: Modulation Depth
-							case 0x01:
-								pmidich->pitchbendrange = value;
-								break;
-							// Bn.07.xx: Volume
-							case 0x07:
-								pmidich->volume = (BYTE)(midivolumetolinear(value) >> 9);
-								break;
-							// Bn.0B.xx: Expression
-							case 0x0B:
-								pmidich->expression = (BYTE)(midivolumetolinear(value) >> 9);
-								break;
-							// Bn.0A.xx: Pan
-							case 0x0A:
-								pmidich->pan = value * 2;
-								break;
-							// Bn.20.xx: Bank Select LSB (GS)
-							case 0x20:
-								pmidich->bank &= (0x7F << 7);
-								pmidich->bank |= value;
-								break;
-							// Bn.79.00: Reset All Controllers (GM)
-							case 0x79:
-								pmidich->modulation = 0;
-								pmidich->expression = 128;
-								pmidich->pitchbend = 0x2000;
-								pmidich->pitchbendrange = 64;
-								// Should also reset pedals (40h-43h), NRP, RPN, aftertouch
-								break;
-							// Bn.78.00: All Sound Off (GS)
-							// Bn.7B.00: All Notes Off (GM)
-							case 0x78:
-							case 0x7B:
-								if (value == 0x00)
-								{
-									// All Notes Off
-									for (UINT k=0; k<m_nChannels; k++)
-									{
-										if (chnstate[k].note)
-										{
-											chnstate[k].flags |= CHNSTATE_NOTEOFFPENDING;
-											chnstate[k].note = 0;
-										}
-									}
-								}
-								break;
-							////////////////////////////////////
-							// Controller List
-							//
-							// Bn.02.xx: Breath Control
-							// Bn.04.xx: Foot Pedal
-							// Bn.05.xx: Portamento Time (Glissando Time)
-							// Bn.06.xx: Data Entry MSB
-							// Bn.08.xx: Balance
-							// Bn.10-13.xx: GP Control #1-#4
-							// Bn.20-3F.xx: Data LSB for controllers 0-31
-							// Bn.26.xx: Data Entry LSB
-							// Bn.40.xx: Hold Pedal #1
-							// Bn.41.xx: Portamento (GS)
-							// Bn.42.xx: Sostenuto (GS)
-							// Bn.43.xx: Soft Pedal (GS)
-							// Bn.44.xx: Legato Pedal
-							// Bn.45.xx: Hold Pedal #2
-							// Bn.46.xx: Sound Variation
-							// Bn.47.xx: Sound Timbre
-							// Bn.48.xx: Sound Release Time
-							// Bn.49.xx: Sound Attack Time
-							// Bn.4A.xx: Sound Brightness
-							// Bn.4B-4F.xx: Sound Control #6-#10
-							// Bn.50-53.xx: GP Control #5-#8
-							// Bn.54.xx: Portamento Control (GS)
-							// Bn.5B.xx: Reverb Level (GS)
-							// Bn.5C.xx: Tremolo Depth
-							// Bn.5D.xx: Chorus Level (GS)
-							// Bn.5E.xx: Celeste Depth
-							// Bn.5F.xx: Phaser Depth
-							// Bn.60.xx: Data Increment
-							// Bn.61.xx: Data Decrement
-							// Bn.62.xx: Non-RPN Parameter LSB (GS)
-							// Bn.63.xx: Non-RPN Parameter MSB (GS)
-							// Bn.64.xx: RPN Parameter LSB (GM)
-							// Bn.65.xx: RPN Parameter MSB (GM)
-							// Bn.7A.00: Local On/Off
-							// Bn.7C.00: Omni Mode Off
-							// Bn.7D.00: Omni Mode On
-							// Bn.7E.mm: Mono Mode On
-							// Bn.7F.00: Poly Mode On
-							}
-						}
-						break;
-
-					////////////////////////////////
-					// C0.pp: Program Change
-					case 0xC0:
-						{
-							pmidich->program = ptrk->ptracks[0] & 0x7F;
-							ptrk->ptracks++;
-						}
-						break;
-
-					////////////////////////////////
-					// D0: Channel Aftertouch (Polyphonic Key Pressure)
-					case 0xD0:
-						{
-							ptrk->ptracks++;
-						}
-						break;
-					
-					////////////////////////////////
-					// E0: Pitch Bend
-					case 0xE0:
-						{
-							pmidich->pitchbend = (WORD)(((UINT)ptrk->ptracks[1] << 7) + (ptrk->ptracks[0] & 0x7F));
-							for (UINT i=0; i<128; i++) if (pmidich->note_on[i])
-							{
-								UINT nchn = pmidich->note_on[i]-1;
-								if (chnstate[nchn].parent == midich)
-								{
-									chnstate[nchn].pitchdest = pmidich->pitchbend;
-								}
-							}
-							ptrk->ptracks+=2;
-						}
-						break;
-
-					//////////////////////////////////////
-					// F0 & Unsupported commands: skip it
-					default:
-						ptrk->ptracks++;
-					}
-				}} // switch+default
-				// Process to next event
-				if (ptrk->ptracks)
-				{
-					ptrk->nexteventtime += getmidilong(ptrk->ptracks, ptrk->ptrmax);
-				}
-				if (ptrk->ptracks >= ptrk->ptrmax) ptrk->ptracks = NULL;
-			}
-			// End reached?
-			if (ptrk->ptracks >= ptrk->ptrmax) ptrk->ptracks = NULL;
-		}
-
-		////////////////////////////////////////////////////////////////////
-		// Move to next row
-		if (!(dwGlobalFlags & MIDIGLOBAL_FROZEN))
-		{
-			// Check MOD channels status
-			for (UINT ichn=0; ichn<m_nChannels; ichn++)
-			{
-				// Pending Global Effects ?
-				if (!m[ichn].command)
-				{
-					if ((chnstate[ichn].pitchsrc != chnstate[ichn].pitchdest) && (chnstate[ichn].parent))
-					{
-						int newpitch = chnstate[ichn].pitchdest;
-						int pitchbendrange = midichstate[chnstate[ichn].parent-1].pitchbendrange;
-						// +/- 256 for +/- pitch bend range
-						int slideamount = (newpitch - (int)chnstate[ichn].pitchsrc) / (int)32;
-						if (slideamount)
-						{
-							const int ppdiv = (16 * 128 * (gnMidiImportSpeed-1));
-							newpitch = (int)chnstate[ichn].pitchsrc + slideamount;
-							if (slideamount < 0)
-							{
-								int param = (-slideamount * pitchbendrange + ppdiv/2) / ppdiv;
-								if (param >= 0x80) param = 0x80;
-								if (param > 0)
-								{
-									m[ichn].param = (BYTE)param;
-									m[ichn].command = CMD_PORTAMENTODOWN;
-								}
-							} else
-							{
-								int param = (slideamount * pitchbendrange + ppdiv/2) / ppdiv;
-								if (param >= 0x80) param = 0x80;
-								if (param > 0)
-								{
-									m[ichn].param = (BYTE)param;
-									m[ichn].command = CMD_PORTAMENTOUP;
-								}
-							}
-						}
-						chnstate[ichn].pitchsrc = (WORD)newpitch;
-
-					} else
-					if (dwGlobalFlags & MIDIGLOBAL_UPDATETEMPO)
-					{
-						m[ichn].command = CMD_TEMPO;
-						m[ichn].param = (BYTE)tempo;
-						dwGlobalFlags &= ~MIDIGLOBAL_UPDATETEMPO;
-					} else
-					if (dwGlobalFlags & MIDIGLOBAL_UPDATEMASTERVOL)
-					{
-						m[ichn].command = CMD_GLOBALVOLUME;
-						m[ichn].param = midimastervol >> 1; // 0-128
-						dwGlobalFlags &= ~MIDIGLOBAL_UPDATEMASTERVOL;
-					}
-				}
-				// Check pending noteoff events for m[ichn]
-				if (!m[ichn].note)
-				{
-					if (chnstate[ichn].flags & CHNSTATE_NOTEOFFPENDING)
-					{
-						chnstate[ichn].flags &= ~CHNSTATE_NOTEOFFPENDING;
-						m[ichn].note = 0xFF;
-					}
-					// Check State of channel
-					chnstate[ichn].idlecount++;
-					if ((chnstate[ichn].note) && (chnstate[ichn].idlecount >= 50))
-					{
-						chnstate[ichn].note = 0;
-						m[ichn].note = 0xFF;	// only if not drum channel ?
-					} else
-					if (chnstate[ichn].idlecount >= 500) // 20secs of inactivity
-					{
-						chnstate[ichn].idlecount = 0;
-						chnstate[ichn].parent = 0;
-					}
-				}
-			}
-
-			if ((++row) >= PatternSize[pat])
-			{
-				pat++;
-				if (pat >= MAX_PATTERNS-1) break;
-				Order[pat] = pat;
-				Order[pat+1] = 0xFF;
-				row = 0;
-			}
-		}
-
-		// Increase midi clock
-		midi_clock += nTickMultiplier;
-	} while (!(dwGlobalFlags & MIDIGLOBAL_SONGENDED));
-	return TRUE;
-}
-
-
--- a/src/modplug/plugin.cxx	Mon Apr 28 18:24:46 2008 +0300
+++ b/src/modplug/plugin.cxx	Wed Apr 30 13:29:56 2008 +0300
@@ -89,6 +89,7 @@
 
 InputPlugin gModPlug =
 {
+    /* Common plugin fields */
     NULL,
     NULL,
     (gchar *)"ModPlug Audio Plugin",
@@ -97,6 +98,8 @@
     ShowAboutBox,
     ShowConfigureBox,
     FALSE,
+
+    /* Input plugin fields */
     NULL,
     NULL,
     PlayFile,
--- a/src/modplug/sndfile.cxx	Mon Apr 28 18:24:46 2008 +0300
+++ b/src/modplug/sndfile.cxx	Wed Apr 30 13:29:56 2008 +0300
@@ -165,7 +165,6 @@
 		 && (!ReadAMF(lpStream, dwMemLength))
 		 && (!ReadPSM(lpStream, dwMemLength))
 		 && (!ReadMT2(lpStream, dwMemLength))
-		 && (!ReadMID(lpStream, dwMemLength))
 		 && (!ReadMod(lpStream, dwMemLength))) m_nType = MOD_TYPE_NONE;
 #ifdef MMCMP_SUPPORT
 		if (bMMCmp)
--- a/src/modplug/sndfile.h	Mon Apr 28 18:24:46 2008 +0300
+++ b/src/modplug/sndfile.h	Wed Apr 30 13:29:56 2008 +0300
@@ -649,9 +649,7 @@
 	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);
-	BOOL ReadMID(LPCBYTE lpStream, DWORD dwMemLength);
 	// MOD Convert function
 	UINT GetBestSaveFormat() const;
 	UINT GetSaveFormats() const;