[Scummvm-cvs-logs] SF.net SVN: scummvm:[47416] scummvm/trunk/engines/sci/sound/softseq

waltervn at users.sourceforge.net waltervn at users.sourceforge.net
Thu Jan 21 17:24:48 CET 2010


Revision: 47416
          http://scummvm.svn.sourceforge.net/scummvm/?rev=47416&view=rev
Author:   waltervn
Date:     2010-01-21 16:24:47 +0000 (Thu, 21 Jan 2010)

Log Message:
-----------
SCI: Add MT-32 to GM mapping

Modified Paths:
--------------
    scummvm/trunk/engines/sci/sound/softseq/midi.cpp

Added Paths:
-----------
    scummvm/trunk/engines/sci/sound/softseq/map-mt32-to-gm.h

Added: scummvm/trunk/engines/sci/sound/softseq/map-mt32-to-gm.h
===================================================================
--- scummvm/trunk/engines/sci/sound/softseq/map-mt32-to-gm.h	                        (rev 0)
+++ scummvm/trunk/engines/sci/sound/softseq/map-mt32-to-gm.h	2010-01-21 16:24:47 UTC (rev 47416)
@@ -0,0 +1,552 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+namespace Sci {
+
+/* Patch not mapped */
+#define MIDI_UNMAPPED 0xff
+/* Patch mapped to rhythm key */
+#define MIDI_MAPPED_TO_RHYTHM 0xfe
+
+struct Mt32ToGmMap {
+	const char *name;
+	uint8 gmInstr;
+	uint8 gmRhythmKey;
+};
+
+static const char *GmInstrumentNames[] = {
+	/*000*/  "Acoustic Grand Piano",
+	/*001*/  "Bright Acoustic Piano",
+	/*002*/  "Electric Grand Piano",
+	/*003*/  "Honky-tonk Piano",
+	/*004*/  "Electric Piano 1",
+	/*005*/  "Electric Piano 2",
+	/*006*/  "Harpsichord",
+	/*007*/  "Clavinet",
+	/*008*/  "Celesta",
+	/*009*/  "Glockenspiel",
+	/*010*/  "Music Box",
+	/*011*/  "Vibraphone",
+	/*012*/  "Marimba",
+	/*013*/  "Xylophone",
+	/*014*/  "Tubular Bells",
+	/*015*/  "Dulcimer",
+	/*016*/  "Drawbar Organ",
+	/*017*/  "Percussive Organ",
+	/*018*/  "Rock Organ",
+	/*019*/  "Church Organ",
+	/*020*/  "Reed Organ",
+	/*021*/  "Accordion",
+	/*022*/  "Harmonica",
+	/*023*/  "Tango Accordion",
+	/*024*/  "Acoustic Guitar (nylon)",
+	/*025*/  "Acoustic Guitar (steel)",
+	/*026*/  "Electric Guitar (jazz)",
+	/*027*/  "Electric Guitar (clean)",
+	/*028*/  "Electric Guitar (muted)",
+	/*029*/  "Overdriven Guitar",
+	/*030*/  "Distortion Guitar",
+	/*031*/  "Guitar Harmonics",
+	/*032*/  "Acoustic Bass",
+	/*033*/  "Electric Bass (finger)",
+	/*034*/  "Electric Bass (pick)",
+	/*035*/  "Fretless Bass",
+	/*036*/  "Slap Bass 1",
+	/*037*/  "Slap Bass 2",
+	/*038*/  "Synth Bass 1",
+	/*039*/  "Synth Bass 2",
+	/*040*/  "Violin",
+	/*041*/  "Viola",
+	/*042*/  "Cello",
+	/*043*/  "Contrabass",
+	/*044*/  "Tremolo Strings",
+	/*045*/  "Pizzicato Strings",
+	/*046*/  "Orchestral Harp",
+	/*047*/  "Timpani",
+	/*048*/  "String Ensemble 1",
+	/*049*/  "String Ensemble 2",
+	/*050*/  "SynthStrings 1",
+	/*051*/  "SynthStrings 2",
+	/*052*/  "Choir Aahs",
+	/*053*/  "Voice Oohs",
+	/*054*/  "Synth Voice",
+	/*055*/  "Orchestra Hit",
+	/*056*/  "Trumpet",
+	/*057*/  "Trombone",
+	/*058*/  "Tuba",
+	/*059*/  "Muted Trumpet",
+	/*060*/  "French Horn",
+	/*061*/  "Brass Section",
+	/*062*/  "SynthBrass 1",
+	/*063*/  "SynthBrass 2",
+	/*064*/  "Soprano Sax",
+	/*065*/  "Alto Sax",
+	/*066*/  "Tenor Sax",
+	/*067*/  "Baritone Sax",
+	/*068*/  "Oboe",
+	/*069*/  "English Horn",
+	/*070*/  "Bassoon",
+	/*071*/  "Clarinet",
+	/*072*/  "Piccolo",
+	/*073*/  "Flute",
+	/*074*/  "Recorder",
+	/*075*/  "Pan Flute",
+	/*076*/  "Blown Bottle",
+	/*077*/  "Shakuhachi",
+	/*078*/  "Whistle",
+	/*079*/  "Ocarina",
+	/*080*/  "Lead 1 (square)",
+	/*081*/  "Lead 2 (sawtooth)",
+	/*082*/  "Lead 3 (calliope)",
+	/*083*/  "Lead 4 (chiff)",
+	/*084*/  "Lead 5 (charang)",
+	/*085*/  "Lead 6 (voice)",
+	/*086*/  "Lead 7 (fifths)",
+	/*087*/  "Lead 8 (bass+lead)",
+	/*088*/  "Pad 1 (new age)",
+	/*089*/  "Pad 2 (warm)",
+	/*090*/  "Pad 3 (polysynth)",
+	/*091*/  "Pad 4 (choir)",
+	/*092*/  "Pad 5 (bowed)",
+	/*093*/  "Pad 6 (metallic)",
+	/*094*/  "Pad 7 (halo)",
+	/*095*/  "Pad 8 (sweep)",
+	/*096*/  "FX 1 (rain)",
+	/*097*/  "FX 2 (soundtrack)",
+	/*098*/  "FX 3 (crystal)",
+	/*099*/  "FX 4 (atmosphere)",
+	/*100*/  "FX 5 (brightness)",
+	/*101*/  "FX 6 (goblins)",
+	/*102*/  "FX 7 (echoes)",
+	/*103*/  "FX 8 (sci-fi)",
+	/*104*/  "Sitar",
+	/*105*/  "Banjo",
+	/*106*/  "Shamisen",
+	/*107*/  "Koto",
+	/*108*/  "Kalimba",
+	/*109*/  "Bag pipe",
+	/*110*/  "Fiddle",
+	/*111*/  "Shannai",
+	/*112*/  "Tinkle Bell",
+	/*113*/  "Agogo",
+	/*114*/  "Steel Drums",
+	/*115*/  "Woodblock",
+	/*116*/  "Taiko Drum",
+	/*117*/  "Melodic Tom",
+	/*118*/  "Synth Drum",
+	/*119*/  "Reverse Cymbal",
+	/*120*/  "Guitar Fret Noise",
+	/*121*/  "Breath Noise",
+	/*122*/  "Seashore",
+	/*123*/  "Bird Tweet",
+	/*124*/  "Telephone Ring",
+	/*125*/  "Helicopter",
+	/*126*/  "Applause",
+	/*127*/  "Gunshot"
+};
+
+/* The GM Percussion map is downwards compatible to the MT32 map, which is used in SCI */
+static const char *GmPercussionNames[] = {
+	/*00*/  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/*10*/  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/*20*/  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/*30*/  0, 0, 0, 0,
+	/* The preceeding percussions are not covered by the GM standard */
+	/*34*/  "Acoustic Bass Drum",
+	/*35*/  "Bass Drum 1",
+	/*36*/  "Side Stick",
+	/*37*/  "Acoustic Snare",
+	/*38*/  "Hand Clap",
+	/*39*/  "Electric Snare",
+	/*40*/  "Low Floor Tom",
+	/*41*/  "Closed Hi-Hat",
+	/*42*/  "High Floor Tom",
+	/*43*/  "Pedal Hi-Hat",
+	/*44*/  "Low Tom",
+	/*45*/  "Open Hi-Hat",
+	/*46*/  "Low-Mid Tom",
+	/*47*/  "Hi-Mid Tom",
+	/*48*/  "Crash Cymbal 1",
+	/*49*/  "High Tom",
+	/*50*/  "Ride Cymbal 1",
+	/*51*/  "Chinese Cymbal",
+	/*52*/  "Ride Bell",
+	/*53*/  "Tambourine",
+	/*54*/  "Splash Cymbal",
+	/*55*/  "Cowbell",
+	/*56*/  "Crash Cymbal 2",
+	/*57*/  "Vibraslap",
+	/*58*/  "Ride Cymbal 2",
+	/*59*/  "Hi Bongo",
+	/*60*/  "Low Bongo",
+	/*61*/  "Mute Hi Conga",
+	/*62*/  "Open Hi Conga",
+	/*63*/  "Low Conga",
+	/*64*/  "High Timbale",
+	/*65*/  "Low Timbale",
+	/*66*/  "High Agogo",
+	/*67*/  "Low Agogo",
+	/*68*/  "Cabasa",
+	/*69*/  "Maracas",
+	/*70*/  "Short Whistle",
+	/*71*/  "Long Whistle",
+	/*72*/  "Short Guiro",
+	/*73*/  "Long Guiro",
+	/*74*/  "Claves",
+	/*75*/  "Hi Wood Block",
+	/*76*/  "Low Wood Block",
+	/*77*/  "Mute Cuica",
+	/*78*/  "Open Cuica",
+	/*79*/  "Mute Triangle",
+	/*80*/  "Open Triangle"
+};
+
+/*******************************************
+ * Fancy instrument mappings begin here... *
+ *******************************************/
+
+
+static const Mt32ToGmMap Mt32PresetTimbreMaps[] = {
+	/*000*/  {"AcouPiano1", 0, MIDI_UNMAPPED},
+	/*001*/  {"AcouPiano2", 1, MIDI_UNMAPPED},
+	/*002*/  {"AcouPiano3", 0, MIDI_UNMAPPED},
+	/*003*/  {"ElecPiano1", 4, MIDI_UNMAPPED},
+	/*004*/  {"ElecPiano2", 5, MIDI_UNMAPPED},
+	/*005*/  {"ElecPiano3", 4, MIDI_UNMAPPED},
+	/*006*/  {"ElecPiano4", 5, MIDI_UNMAPPED},
+	/*007*/  {"Honkytonk ", 3, MIDI_UNMAPPED},
+	/*008*/  {"Elec Org 1", 16, MIDI_UNMAPPED},
+	/*009*/  {"Elec Org 2", 17, MIDI_UNMAPPED},
+	/*010*/  {"Elec Org 3", 18, MIDI_UNMAPPED},
+	/*011*/  {"Elec Org 4", 18, MIDI_UNMAPPED},
+	/*012*/  {"Pipe Org 1", 19, MIDI_UNMAPPED},
+	/*013*/  {"Pipe Org 2", 19, MIDI_UNMAPPED},
+	/*014*/  {"Pipe Org 3", 20, MIDI_UNMAPPED},
+	/*015*/  {"Accordion ", 21, MIDI_UNMAPPED},
+	/*016*/  {"Harpsi 1  ", 6, MIDI_UNMAPPED},
+	/*017*/  {"Harpsi 2  ", 6, MIDI_UNMAPPED},
+	/*018*/  {"Harpsi 3  ", 6, MIDI_UNMAPPED},
+	/*019*/  {"Clavi 1   ", 7, MIDI_UNMAPPED},
+	/*020*/  {"Clavi 2   ", 7, MIDI_UNMAPPED},
+	/*021*/  {"Clavi 3   ", 7, MIDI_UNMAPPED},
+	/*022*/  {"Celesta 1 ", 8, MIDI_UNMAPPED},
+	/*023*/  {"Celesta 2 ", 8, MIDI_UNMAPPED},
+	/*024*/  {"Syn Brass1", 62, MIDI_UNMAPPED},
+	/*025*/  {"Syn Brass2", 63, MIDI_UNMAPPED},
+	/*026*/  {"Syn Brass3", 62, MIDI_UNMAPPED},
+	/*027*/  {"Syn Brass4", 63, MIDI_UNMAPPED},
+	/*028*/  {"Syn Bass 1", 38, MIDI_UNMAPPED},
+	/*029*/  {"Syn Bass 2", 39, MIDI_UNMAPPED},
+	/*030*/  {"Syn Bass 3", 38, MIDI_UNMAPPED},
+	/*031*/  {"Syn Bass 4", 39, MIDI_UNMAPPED},
+	/*032*/  {"Fantasy   ", 88, MIDI_UNMAPPED},
+	/*033*/  {"Harmo Pan ", 89, MIDI_UNMAPPED},
+	/*034*/  {"Chorale   ", 52, MIDI_UNMAPPED},
+	/*035*/  {"Glasses   ", 98, MIDI_UNMAPPED},
+	/*036*/  {"Soundtrack", 97, MIDI_UNMAPPED},
+	/*037*/  {"Atmosphere", 99, MIDI_UNMAPPED},
+	/*038*/  {"Warm Bell ", 89, MIDI_UNMAPPED},
+	/*039*/  {"Funny Vox ", 85, MIDI_UNMAPPED},
+	/*040*/  {"Echo Bell ", 39, MIDI_UNMAPPED},
+	/*041*/  {"Ice Rain  ", 101, MIDI_UNMAPPED},
+	/*042*/  {"Oboe 2001 ", 68, MIDI_UNMAPPED},
+	/*043*/  {"Echo Pan  ", 87, MIDI_UNMAPPED},
+	/*044*/  {"DoctorSolo", 86, MIDI_UNMAPPED},
+	/*045*/  {"Schooldaze", 103, MIDI_UNMAPPED},
+	/*046*/  {"BellSinger", 88, MIDI_UNMAPPED},
+	/*047*/  {"SquareWave", 80, MIDI_UNMAPPED},
+	/*048*/  {"Str Sect 1", 48, MIDI_UNMAPPED},
+	/*049*/  {"Str Sect 2", 48, MIDI_UNMAPPED},
+	/*050*/  {"Str Sect 3", 49, MIDI_UNMAPPED},
+	/*051*/  {"Pizzicato ", 45, MIDI_UNMAPPED},
+	/*052*/  {"Violin 1  ", 40, MIDI_UNMAPPED},
+	/*053*/  {"Violin 2  ", 40, MIDI_UNMAPPED},
+	/*054*/  {"Cello 1   ", 42, MIDI_UNMAPPED},
+	/*055*/  {"Cello 2   ", 42, MIDI_UNMAPPED},
+	/*056*/  {"Contrabass", 43, MIDI_UNMAPPED},
+	/*057*/  {"Harp 1    ", 46, MIDI_UNMAPPED},
+	/*058*/  {"Harp 2    ", 46, MIDI_UNMAPPED},
+	/*059*/  {"Guitar 1  ", 24, MIDI_UNMAPPED},
+	/*060*/  {"Guitar 2  ", 25, MIDI_UNMAPPED},
+	/*061*/  {"Elec Gtr 1", 26, MIDI_UNMAPPED},
+	/*062*/  {"Elec Gtr 2", 27, MIDI_UNMAPPED},
+	/*063*/  {"Sitar     ", 104, MIDI_UNMAPPED},
+	/*064*/  {"Acou Bass1", 32, MIDI_UNMAPPED},
+	/*065*/  {"Acou Bass2", 33, MIDI_UNMAPPED},
+	/*066*/  {"Elec Bass1", 34, MIDI_UNMAPPED},
+	/*067*/  {"Elec Bass2", 39, MIDI_UNMAPPED},
+	/*068*/  {"Slap Bass1", 36, MIDI_UNMAPPED},
+	/*069*/  {"Slap Bass2", 37, MIDI_UNMAPPED},
+	/*070*/  {"Fretless 1", 35, MIDI_UNMAPPED},
+	/*071*/  {"Fretless 2", 35, MIDI_UNMAPPED},
+	/*072*/  {"Flute 1   ", 73, MIDI_UNMAPPED},
+	/*073*/  {"Flute 2   ", 73, MIDI_UNMAPPED},
+	/*074*/  {"Piccolo 1 ", 72, MIDI_UNMAPPED},
+	/*075*/  {"Piccolo 2 ", 72, MIDI_UNMAPPED},
+	/*076*/  {"Recorder  ", 74, MIDI_UNMAPPED},
+	/*077*/  {"Panpipes  ", 75, MIDI_UNMAPPED},
+	/*078*/  {"Sax 1     ", 64, MIDI_UNMAPPED},
+	/*079*/  {"Sax 2     ", 65, MIDI_UNMAPPED},
+	/*080*/  {"Sax 3     ", 66, MIDI_UNMAPPED},
+	/*081*/  {"Sax 4     ", 67, MIDI_UNMAPPED},
+	/*082*/  {"Clarinet 1", 71, MIDI_UNMAPPED},
+	/*083*/  {"Clarinet 2", 71, MIDI_UNMAPPED},
+	/*084*/  {"Oboe      ", 68, MIDI_UNMAPPED},
+	/*085*/  {"Engl Horn ", 69, MIDI_UNMAPPED},
+	/*086*/  {"Bassoon   ", 70, MIDI_UNMAPPED},
+	/*087*/  {"Harmonica ", 22, MIDI_UNMAPPED},
+	/*088*/  {"Trumpet 1 ", 56, MIDI_UNMAPPED},
+	/*089*/  {"Trumpet 2 ", 56, MIDI_UNMAPPED},
+	/*090*/  {"Trombone 1", 57, MIDI_UNMAPPED},
+	/*091*/  {"Trombone 2", 57, MIDI_UNMAPPED},
+	/*092*/  {"Fr Horn 1 ", 60, MIDI_UNMAPPED},
+	/*093*/  {"Fr Horn 2 ", 60, MIDI_UNMAPPED},
+	/*094*/  {"Tuba      ", 58, MIDI_UNMAPPED},
+	/*095*/  {"Brs Sect 1", 61, MIDI_UNMAPPED},
+	/*096*/  {"Brs Sect 2", 61, MIDI_UNMAPPED},
+	/*097*/  {"Vibe 1    ", 11, MIDI_UNMAPPED},
+	/*098*/  {"Vibe 2    ", 11, MIDI_UNMAPPED},
+	/*099*/  {"Syn Mallet", 15, MIDI_UNMAPPED},
+	/*100*/  {"Wind Bell ", 88, MIDI_UNMAPPED},
+	/*101*/  {"Glock     ", 9, MIDI_UNMAPPED},
+	/*102*/  {"Tube Bell ", 14, MIDI_UNMAPPED},
+	/*103*/  {"Xylophone ", 13, MIDI_UNMAPPED},
+	/*104*/  {"Marimba   ", 12, MIDI_UNMAPPED},
+	/*105*/  {"Koto      ", 107, MIDI_UNMAPPED},
+	/*106*/  {"Sho       ", 111, MIDI_UNMAPPED},
+	/*107*/  {"Shakuhachi", 77, MIDI_UNMAPPED},
+	/*108*/  {"Whistle 1 ", 78, MIDI_UNMAPPED},
+	/*109*/  {"Whistle 2 ", 78, MIDI_UNMAPPED},
+	/*110*/  {"BottleBlow", 76, MIDI_UNMAPPED},
+	/*111*/  {"BreathPipe", 121, MIDI_UNMAPPED},
+	/*112*/  {"Timpani   ", 47, MIDI_UNMAPPED},
+	/*113*/  {"MelodicTom", 117, MIDI_UNMAPPED},
+	/*114*/  {"Deep Snare", MIDI_MAPPED_TO_RHYTHM, 37},
+	/*115*/  {"Elec Perc1", 115, MIDI_UNMAPPED}, /* ? */
+	/*116*/  {"Elec Perc2", 118, MIDI_UNMAPPED}, /* ? */
+	/*117*/  {"Taiko     ", 116, MIDI_UNMAPPED},
+	/*118*/  {"Taiko Rim ", 118, MIDI_UNMAPPED},
+	/*119*/  {"Cymbal    ", MIDI_MAPPED_TO_RHYTHM, 50},
+	/*120*/  {"Castanets ", MIDI_UNMAPPED, MIDI_UNMAPPED},
+	/*121*/  {"Triangle  ", 112, MIDI_UNMAPPED},
+	/*122*/  {"Orche Hit ", 55, MIDI_UNMAPPED},
+	/*123*/  {"Telephone ", 124, MIDI_UNMAPPED},
+	/*124*/  {"Bird Tweet", 123, MIDI_UNMAPPED},
+	/*125*/  {"OneNoteJam", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* ? */
+	/*126*/  {"WaterBells", 98, MIDI_UNMAPPED},
+	/*127*/  {"JungleTune", MIDI_UNMAPPED, MIDI_UNMAPPED} /* ? */
+};
+
+static const Mt32ToGmMap Mt32RhythmTimbreMaps[] = {
+	/*00*/  {"Acou BD   ", MIDI_MAPPED_TO_RHYTHM, 34},
+	/*01*/  {"Acou SD   ", MIDI_MAPPED_TO_RHYTHM, 37},
+	/*02*/  {"Acou HiTom", 117, 49},
+	/*03*/  {"AcouMidTom", 117, 46},
+	/*04*/  {"AcouLowTom", 117, 40},
+	/*05*/  {"Elec SD   ", MIDI_MAPPED_TO_RHYTHM, 39},
+	/*06*/  {"Clsd HiHat", MIDI_MAPPED_TO_RHYTHM, 41},
+	/*07*/  {"OpenHiHat1", MIDI_MAPPED_TO_RHYTHM, 45},
+	/*08*/  {"Crash Cym ", MIDI_MAPPED_TO_RHYTHM, 48},
+	/*09*/  {"Ride Cym  ", MIDI_MAPPED_TO_RHYTHM, 50},
+	/*10*/  {"Rim Shot  ", MIDI_MAPPED_TO_RHYTHM, 36},
+	/*11*/  {"Hand Clap ", MIDI_MAPPED_TO_RHYTHM, 38},
+	/*12*/  {"Cowbell   ", MIDI_MAPPED_TO_RHYTHM, 55},
+	/*13*/  {"Mt HiConga", MIDI_MAPPED_TO_RHYTHM, 61},
+	/*14*/  {"High Conga", MIDI_MAPPED_TO_RHYTHM, 62},
+	/*15*/  {"Low Conga ", MIDI_MAPPED_TO_RHYTHM, 63},
+	/*16*/  {"Hi Timbale", MIDI_MAPPED_TO_RHYTHM, 64},
+	/*17*/  {"LowTimbale", MIDI_MAPPED_TO_RHYTHM, 65},
+	/*18*/  {"High Bongo", MIDI_MAPPED_TO_RHYTHM, 59},
+	/*19*/  {"Low Bongo ", MIDI_MAPPED_TO_RHYTHM, 60},
+	/*20*/  {"High Agogo", 113, 66},
+	/*21*/  {"Low Agogo ", 113, 67},
+	/*22*/  {"Tambourine", MIDI_MAPPED_TO_RHYTHM, 53},
+	/*23*/  {"Claves    ", MIDI_MAPPED_TO_RHYTHM, 74},
+	/*24*/  {"Maracas   ", MIDI_MAPPED_TO_RHYTHM, 69},
+	/*25*/  {"SmbaWhis L", 78, 71},
+	/*26*/  {"SmbaWhis S", 78, 70},
+	/*27*/  {"Cabasa    ", MIDI_MAPPED_TO_RHYTHM, 68},
+	/*28*/  {"Quijada   ", MIDI_MAPPED_TO_RHYTHM, 72},
+	/*29*/  {"OpenHiHat2", MIDI_MAPPED_TO_RHYTHM, 43}
+};
+
+static const uint8 Mt32PresetRhythmKeymap[] = {
+	MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED,
+	MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED,
+	MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED,
+	MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, 34, 34, 36, 37, 38, 39,
+	40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+	50, MIDI_UNMAPPED, MIDI_UNMAPPED, 53, MIDI_UNMAPPED, 55, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, 59,
+	60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+	70, 71, 72, MIDI_UNMAPPED, 74, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED,
+	MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED,
+	MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED,
+	MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED,
+	MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED,
+	MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED, MIDI_UNMAPPED
+};
+
+/* +++ - Don't change unless you've got a good reason
+   ++  - Looks good, sounds ok
+   +   - Not too bad, but is it right?
+   ?   - Where do I map this one?
+   ??  - Any good ideas?
+   ??? - I'm clueless?
+   R   - Rhythm... */
+static const Mt32ToGmMap Mt32MemoryTimbreMaps[] = {
+	{"AccPnoKA2 ", 1, MIDI_UNMAPPED},     /* ++ (KQ1) */
+	{"Acou BD   ", MIDI_MAPPED_TO_RHYTHM, 34},   /* R (PQ2) */
+	{"Acou SD   ", MIDI_MAPPED_TO_RHYTHM, 37},   /* R (PQ2) */
+	{"AcouPnoKA ", 0, MIDI_UNMAPPED},     /* ++ (KQ1) */
+	{"BASS      ", 32, MIDI_UNMAPPED},    /* + (LSL3) */
+	{"BASSOONPCM", 70, MIDI_UNMAPPED},    /* + (CB) */
+	{"BEACH WAVE", 122, MIDI_UNMAPPED},   /* + (LSL3) */
+	{"BagPipes  ", 109, MIDI_UNMAPPED},
+	{"BassPizzMS", 45, MIDI_UNMAPPED},    /* ++ (HQ) */
+	{"BassoonKA ", 70, MIDI_UNMAPPED},    /* ++ (KQ1) */
+	{"Bell    MS", 112, MIDI_UNMAPPED},   /* ++ (iceMan) */
+	{"Bells   MS", 112, MIDI_UNMAPPED},   /* + (HQ) */
+	{"Big Bell  ", 14, MIDI_UNMAPPED},    /* + (CB) */
+	{"Bird Tweet", 123, MIDI_UNMAPPED},
+	{"BrsSect MS", 61, MIDI_UNMAPPED},    /* +++ (iceMan) */
+	{"CLAPPING  ", 126, MIDI_UNMAPPED},   /* ++ (LSL3) */
+	{"Cabasa    ", MIDI_MAPPED_TO_RHYTHM, 68},   /* R (HBoG) */
+	{"Calliope  ", 82, MIDI_UNMAPPED},    /* +++ (HQ) */
+	{"CelticHarp", 46, MIDI_UNMAPPED},    /* ++ (CoC) */
+	{"Chicago MS", 1, MIDI_UNMAPPED},     /* ++ (iceMan) */
+	{"Chop      ", 117, MIDI_UNMAPPED},
+	{"Chorale MS", 52, MIDI_UNMAPPED},    /* + (CoC) */
+	{"ClarinetMS", 71, MIDI_UNMAPPED},
+	{"Claves    ", MIDI_MAPPED_TO_RHYTHM, 74},   /* R (PQ2) */
+	{"Claw    MS", 118, MIDI_UNMAPPED},    /* + (HQ) */
+	{"ClockBell ", 14, MIDI_UNMAPPED},    /* + (CB) */
+	{"ConcertCym", MIDI_MAPPED_TO_RHYTHM, 54},   /* R ? (KQ1) */
+	{"Conga   MS", MIDI_MAPPED_TO_RHYTHM, 63},   /* R (HQ) */
+	{"CoolPhone ", 124, MIDI_UNMAPPED},   /* ++ (LSL3) */
+	{"CracklesMS", 115, MIDI_UNMAPPED}, /* ? (CoC, HQ) */
+	{"CreakyD MS", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* ??? (KQ1) */
+	{"Cricket   ", 120, MIDI_UNMAPPED}, /* ? (CB) */
+	{"CrshCymbMS", MIDI_MAPPED_TO_RHYTHM, 56},   /* R +++ (iceMan) */
+	{"CstlGateMS", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* ? (HQ) */
+	{"CymSwellMS", MIDI_MAPPED_TO_RHYTHM, 54},   /* R ? (CoC, HQ) */
+	{"CymbRollKA", MIDI_MAPPED_TO_RHYTHM, 56},   /* R ? (KQ1) */
+	{"Cymbal Lo ", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* R ? (LSL3) */
+	{"card      ", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* ? (HBoG) */
+	{"DirtGtr MS", 30, MIDI_UNMAPPED},    /* + (iceMan) */
+	{"DirtGtr2MS", 29, MIDI_UNMAPPED},    /* + (iceMan) */
+	{"E Bass  MS", 33, MIDI_UNMAPPED},    /* + (SQ3) */
+	{"ElecBassMS", 33, MIDI_UNMAPPED},
+	{"ElecGtr MS", 27, MIDI_UNMAPPED},    /* ++ (iceMan) */
+	{"EnglHornMS", 69, MIDI_UNMAPPED},
+	{"FantasiaKA", 88, MIDI_UNMAPPED},
+	{"Fantasy   ", 99, MIDI_UNMAPPED},    /* + (PQ2) */
+	{"Fantasy2MS", 99, MIDI_UNMAPPED},    /* ++ (CoC, HQ) */
+	{"Filter  MS", 95, MIDI_UNMAPPED},    /* +++ (iceMan) */
+	{"Filter2 MS", 95, MIDI_UNMAPPED},    /* ++ (iceMan) */
+	{"Flame2  MS", 121, MIDI_UNMAPPED},   /* ? (HQ) */
+	{"Flames  MS", 121, MIDI_UNMAPPED},   /* ? (HQ) */
+	{"Flute   MS", 73, MIDI_UNMAPPED},    /* +++ (HQ) */
+	{"FogHorn MS", 58, MIDI_UNMAPPED},
+	{"FrHorn1 MS", 60, MIDI_UNMAPPED},    /* +++ (HQ) */
+	{"FunnyTrmp ", 56, MIDI_UNMAPPED},    /* ++ (CB) */
+	{"GameSnd MS", 80, MIDI_UNMAPPED},
+	{"Glock   MS", 9, MIDI_UNMAPPED},     /* +++ (HQ) */
+	{"Gunshot   ", 127, MIDI_UNMAPPED},   /* +++ (CB) */
+	{"Hammer  MS", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* ? (HQ) */
+	{"Harmonica2", 22, MIDI_UNMAPPED},    /* +++ (CB) */
+	{"Harpsi 1  ", 6, MIDI_UNMAPPED},     /* + (HBoG) */
+	{"Harpsi 2  ", 6, MIDI_UNMAPPED},     /* +++ (CB) */
+	{"Heart   MS", 116, MIDI_UNMAPPED},   /* ? (iceMan) */
+	{"Horse1  MS", 115, MIDI_UNMAPPED},   /* ? (CoC, HQ) */
+	{"Horse2  MS", 115, MIDI_UNMAPPED},   /* ? (CoC, HQ) */
+	{"InHale  MS", 121, MIDI_UNMAPPED},   /* ++ (iceMan) */
+	{"KNIFE     ", 120, MIDI_UNMAPPED},   /* ? (LSL3) */
+	{"KenBanjo  ", 105, MIDI_UNMAPPED},   /* +++ (CB) */
+	{"Kiss    MS", 25, MIDI_UNMAPPED},    /* ++ (HQ) */
+	{"KongHit   ", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* ??? (KQ1) */
+	{"Koto      ", 107, MIDI_UNMAPPED},   /* +++ (PQ2) */
+	{"Laser   MS", 81, MIDI_UNMAPPED},    /* ?? (HQ) */
+	{"Meeps   MS", 62, MIDI_UNMAPPED},    /* ? (HQ) */
+	{"MTrak   MS", 62, MIDI_UNMAPPED},    /* ?? (iceMan) */
+	{"MachGun MS", 127, MIDI_UNMAPPED},   /* ? (iceMan) */
+	{"OCEANSOUND", 122, MIDI_UNMAPPED},   /* + (LSL3) */
+	{"Oboe 2001 ", 68, MIDI_UNMAPPED},    /* + (PQ2) */
+	{"Ocean   MS", 122, MIDI_UNMAPPED},   /* + (iceMan) */
+	{"PPG 2.3 MS", 75, MIDI_UNMAPPED},    /* ? (iceMan) */
+	{"PianoCrank", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* ? (CB) */
+	{"PicSnareMS", MIDI_MAPPED_TO_RHYTHM, 39},   /* R ? (iceMan) */
+	{"PiccoloKA ", 72, MIDI_UNMAPPED},    /* +++ (KQ1) */
+	{"PinkBassMS", 39, MIDI_UNMAPPED},
+	{"Pizz2     ", 45, MIDI_UNMAPPED},    /* ++ (CB) */
+	{"Portcullis", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* ? (KQ1) */
+	{"Raspbry MS", 81, MIDI_UNMAPPED},    /* ? (HQ) */
+	{"RatSqueek ", 72, MIDI_UNMAPPED},    /* ? (CB, CoC) */
+	{"Record78  ", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* +++ (CB) */
+	{"RecorderMS", 74, MIDI_UNMAPPED},    /* +++ (CoC) */
+	{"Red Baron ", 125, MIDI_UNMAPPED},   /* ? (CB) */
+	{"ReedPipMS ", 20, MIDI_UNMAPPED},    /* +++ (Coc) */
+	{"RevCymb MS", 119, MIDI_UNMAPPED},
+	{"RifleShot ", 127, MIDI_UNMAPPED},   /* + (CB) */
+	{"RimShot MS", MIDI_MAPPED_TO_RHYTHM, 36},   /* R */
+	{"SHOWER    ", 52, MIDI_UNMAPPED},    /* ? (LSL3) */
+	{"SQ Bass MS", 32, MIDI_UNMAPPED},    /* + (SQ3) */
+	{"ShakuVibMS", 79, MIDI_UNMAPPED},    /* + (iceMan) */
+	{"SlapBassMS", 36, MIDI_UNMAPPED},    /* +++ (iceMan) */
+	{"Snare   MS", MIDI_MAPPED_TO_RHYTHM, 37},   /* R (HQ) */
+	{"Some Birds", 123, MIDI_UNMAPPED},   /* + (CB) */
+	{"Sonar   MS", 78, MIDI_UNMAPPED},    /* ? (iceMan) */
+	{"Soundtrk2 ", 97, MIDI_UNMAPPED},    /* +++ (CB) */
+	{"Soundtrack", 97, MIDI_UNMAPPED},    /* ++ (CoC) */
+	{"SqurWaveMS", 80, MIDI_UNMAPPED},
+	{"StabBassMS", 34, MIDI_UNMAPPED},    /* + (iceMan) */
+	{"SteelDrmMS", 114, MIDI_UNMAPPED},   /* +++ (iceMan) */
+	{"StrSect1MS", 48, MIDI_UNMAPPED},    /* ++ (HQ) */
+	{"String  MS", 45, MIDI_UNMAPPED},    /* + (CoC) */
+	{"Syn-Choir ", 91, MIDI_UNMAPPED},
+	{"Syn Brass4", 63, MIDI_UNMAPPED},    /* ++ (PQ2) */
+	{"SynBass MS", 38, MIDI_UNMAPPED},
+	{"SwmpBackgr", 120, MIDI_UNMAPPED},    /* ?? (CB,HQ) */
+	{"T-Bone2 MS", 57, MIDI_UNMAPPED},    /* +++ (HQ) */
+	{"Taiko     ", 116, 34},      /* +++ (Coc) */
+	{"Taiko Rim ", 118, 36},      /* +++ (LSL3) */
+	{"Timpani1  ", 47, MIDI_UNMAPPED},    /* +++ (CB) */
+	{"Tom     MS", 117, 47},      /* +++ (iceMan) */
+	{"Toms    MS", 117, 47},      /* +++ (CoC, HQ) */
+	{"Tpt1prtl  ", 56, MIDI_UNMAPPED},    /* +++ (KQ1) */
+	{"TriangleMS", 112, 80},      /* R (CoC) */
+	{"Trumpet 1 ", 56, MIDI_UNMAPPED},    /* +++ (CoC) */
+	{"Type    MS", 114, MIDI_UNMAPPED},   /* ? (iceMan) */
+	{"WaterBells", 98, MIDI_UNMAPPED},    /* + (PQ2) */
+	{"WaterFallK", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* ? (KQ1) */
+	{"Whiporill ", 123, MIDI_UNMAPPED},   /* + (CB) */
+	{"Wind      ", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* ? (CB) */
+	{"Wind    MS", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* ? (HQ, iceMan) */
+	{"Wind2   MS", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* ? (CoC) */
+	{"Woodpecker", 115, MIDI_UNMAPPED},   /* ? (CB) */
+	{"WtrFall MS", MIDI_UNMAPPED, MIDI_UNMAPPED}, /* ? (CoC, HQ, iceMan) */
+	{0, 0, 0}
+};
+
+} // End of namespace Sci


Property changes on: scummvm/trunk/engines/sci/sound/softseq/map-mt32-to-gm.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Modified: scummvm/trunk/engines/sci/sound/softseq/midi.cpp
===================================================================
--- scummvm/trunk/engines/sci/sound/softseq/midi.cpp	2010-01-21 09:01:00 UTC (rev 47415)
+++ scummvm/trunk/engines/sci/sound/softseq/midi.cpp	2010-01-21 16:24:47 UTC (rev 47416)
@@ -31,6 +31,7 @@
 
 #include "sci/resource.h"
 #include "sci/sound/softseq/mididriver.h"
+#include "sci/sound/softseq/map-mt32-to-gm.h"
 
 namespace Sci {
 
@@ -63,6 +64,11 @@
 	void readMt32Patch(const byte *data, int size);
 	void readMt32DrvData();
 
+	void mapMt32ToGm(byte *data, size_t size);
+	uint8 lookupGmInstrument(const char *iname);
+	uint8 lookupGmRhythmKey(const char *iname);
+	uint8 getGmInstrument(const Mt32ToGmMap &Mt32Ins);
+
 	void sendMt32SysEx(const uint32 addr, Common::SeekableReadStream *str, int len, bool noDelay);
 	void sendMt32SysEx(const uint32 addr, const byte *buf, int len, bool noDelay);
 	void setMt32Volume(byte volume);
@@ -83,7 +89,7 @@
 		uint8 hold;
 		uint8 volume;
 
-		Channel() : mappedPatch(0xff), patch(0xff), velocityMapIdx(0), playing(false),
+		Channel() : mappedPatch(MIDI_UNMAPPED), patch(MIDI_UNMAPPED), velocityMapIdx(0), playing(false),
 			keyShift(0), volAdjust(0), pan(0x80), hold(0), volume(0x7f) { }
 	};
 
@@ -101,6 +107,11 @@
 	uint8 _patchMap[128];
 	uint8 _velocityMapIdx[128];
 	uint8 _velocityMap[4][128];
+
+	// These are extensions used for our own MT-32 to GM mapping
+	uint8 _pitchBendRange[128];
+	uint8 _percussionVelocityScale[128];
+
 	byte _goodbyeMsg[20];
 	byte _sysExBuf[kMaxSysExSize];
 };
@@ -123,14 +134,28 @@
 }
 
 void MidiPlayer_Midi::noteOn(int channel, int note, int velocity) {
+	uint8 patch = _channels[channel].mappedPatch;
+
 	if (channel == MIDI_RHYTHM_CHANNEL) {
+		if (_percussionMap[note] == MIDI_UNMAPPED) {
+			debugC(kDebugLevelSound, "[Midi] Percussion instrument %i is unmapped", note);
+			return;
+		}
+
 		note = _percussionMap[note];
-		if (note == 0xff)
+		// Scale velocity;
+		velocity = velocity * _percussionVelocityScale[note] / 127;
+	} else if (patch >= 128) {
+		if (patch == MIDI_UNMAPPED)
 			return;
+
+		// Map to rhythm
+		channel = MIDI_RHYTHM_CHANNEL;
+		note = patch - 128;
+
+		// Scale velocity;
+		velocity = velocity * _percussionVelocityScale[note] / 127;
 	} else {
-		if (_channels[channel].mappedPatch == 0xff)
-			return;
-
 		int8 keyshift = _keyShift[channel];
 
 		int shiftNote = note + keyshift;
@@ -210,12 +235,13 @@
 	_channels[channel].patch = patch;
 	_channels[channel].velocityMapIdx = _velocityMapIdx[patch];
 
-	if (_channels[channel].mappedPatch == 0xff)
+	if (_channels[channel].mappedPatch == MIDI_UNMAPPED)
 		resetVol = true;
 
 	_channels[channel].mappedPatch = _patchMap[patch];
 
-	if (_patchMap[patch] == 0xff) {
+	if (_patchMap[patch] == MIDI_UNMAPPED) {
+		debugC(kDebugLevelSound, "[Midi] Channel %i set to unmapped patch %i", channel, patch);
 		_driver->send(0xb0 | channel, 0x7b, 0);
 		_driver->send(0xb0 | channel, 0x40, 0);
 		return;
@@ -233,6 +259,10 @@
 		controlChange(channel, 0x07, _channels[channel].volume);
 	}
 
+	uint8 bendRange = _pitchBendRange[patch];
+	if (bendRange != MIDI_UNMAPPED)
+		_driver->setPitchBendRange(channel, bendRange);
+
 	_driver->send(0xc0 | channel, _patchMap[patch], 0);
 }
 
@@ -539,6 +569,151 @@
 	}
 }
 
+byte MidiPlayer_Midi::lookupGmInstrument(const char *iname) {
+	int i = 0;
+
+	while (Mt32MemoryTimbreMaps[i].name) {
+		if (scumm_strnicmp(iname, Mt32MemoryTimbreMaps[i].name, 10) == 0)
+			return getGmInstrument(Mt32MemoryTimbreMaps[i]);
+		i++;
+	}
+	return MIDI_UNMAPPED;
+}
+
+byte MidiPlayer_Midi::lookupGmRhythmKey(const char *iname) {
+	int i = 0;
+
+	while (Mt32MemoryTimbreMaps[i].name) {
+		if (scumm_strnicmp(iname, Mt32MemoryTimbreMaps[i].name, 10) == 0)
+			return Mt32MemoryTimbreMaps[i].gmRhythmKey;
+		i++;
+	}
+	return MIDI_UNMAPPED;
+}
+
+uint8 MidiPlayer_Midi::getGmInstrument(const Mt32ToGmMap &Mt32Ins) {
+	if (Mt32Ins.gmInstr == MIDI_MAPPED_TO_RHYTHM)
+		return Mt32Ins.gmRhythmKey + 0x80;
+	else
+		return Mt32Ins.gmInstr;
+}
+
+void MidiPlayer_Midi::mapMt32ToGm(byte *data, size_t size) {
+	// FIXME: Clean this up
+	int memtimbres, patches;
+	uint8 group, number, keyshift, finetune, bender_range;
+	uint8 *patchpointer;
+	uint32 pos;
+	int i;
+
+	for (i = 0; i < 128; i++) {
+		_patchMap[i] = getGmInstrument(Mt32PresetTimbreMaps[i]);
+		_pitchBendRange[i] = 12;
+	}
+
+	for (i = 0; i < 128; i++)
+		_percussionMap[i] = Mt32PresetRhythmKeymap[i];
+
+	memtimbres = *(data + 0x1eb);
+	pos = 0x1ec + memtimbres * 0xf6;
+
+	if (size > pos && ((0x100 * *(data + pos) + *(data + pos + 1)) == 0xabcd)) {
+		patches = 96;
+		pos += 2 + 8 * 48;
+	} else
+		patches = 48;
+
+	debugC(kDebugLevelSound, "[MT32-to-GM] %d MT-32 Patches detected", patches);
+	debugC(kDebugLevelSound, "[MT32-to-GM] %d MT-32 Memory Timbres", memtimbres);
+
+	debugC(kDebugLevelSound, "\n[MT32-to-GM] Mapping patches..");
+
+	for (i = 0; i < patches; i++) {
+		char name[11];
+
+		if (i < 48)
+			patchpointer = data + 0x6b + 8 * i;
+		else
+			patchpointer = data + 0x1ec + 8 * (i - 48) + memtimbres * 0xf6 + 2;
+
+		group = *patchpointer;
+		number = *(patchpointer + 1);
+		keyshift = *(patchpointer + 2);
+		finetune = *(patchpointer + 3);
+		bender_range = *(patchpointer + 4);
+
+		debugCN(kDebugLevelSound, "  [%03d] ", i);
+
+		switch (group) {
+		case 1:
+			number += 64;
+			// Fall through
+		case 0:
+			_patchMap[i] = getGmInstrument(Mt32PresetTimbreMaps[number]);
+			debugCN(kDebugLevelSound, "%s -> ", Mt32PresetTimbreMaps[number].name);
+			break;
+		case 2:
+			strncpy(name, (const char *)data + 0x1ec + number * 0xf6, 10);
+			name[10] = 0;
+			_patchMap[i] = lookupGmInstrument(name);
+			debugCN(kDebugLevelSound, "%s -> ", name);
+			break;
+		case 3:
+			_patchMap[i] = getGmInstrument(Mt32RhythmTimbreMaps[number]);
+			debugCN(kDebugLevelSound, "%s -> ", Mt32RhythmTimbreMaps[number].name);
+			break;
+		default:
+			break;
+		}
+
+		if (_patchMap[i] == MIDI_UNMAPPED) {
+			debugC(kDebugLevelSound, "[Unmapped]");
+		} else {
+			if (_patchMap[i] >= 128) {
+				debugC(kDebugLevelSound, "%s [Rhythm]", GmPercussionNames[_patchMap[i] - 128]);
+			} else {
+				debugC(kDebugLevelSound, "%s", GmInstrumentNames[_patchMap[i]]);
+			}
+		}
+
+		_keyShift[i] = CLIP<uint8>(keyshift, 0, 48) - 24;
+		_pitchBendRange[i] = CLIP<uint8>(bender_range, 0, 24);
+	}
+
+	if (size > pos && ((0x100 * *(data + pos) + *(data + pos + 1)) == 0xdcba)) {
+		debugC(kDebugLevelSound, "\n[MT32-to-GM] Mapping percussion..");
+
+		for (i = 0; i < 64 ; i++) {
+			number = *(data + pos + 4 * i + 2);
+
+			debugCN(kDebugLevelSound, "  [%03d] ", i + 23);
+
+			if (number < 64) {
+				char name[11];
+				strncpy(name, (const char *)data + 0x1ec + number * 0xf6, 10);
+				name[10] = 0;
+				debugCN(kDebugLevelSound, "%s -> ", name);
+				_percussionMap[i + 23] = lookupGmRhythmKey(name);
+			} else {
+				if (number < 94) {
+					debugCN(kDebugLevelSound, "%s -> ", Mt32RhythmTimbreMaps[number - 64].name);
+					_percussionMap[i + 23] = Mt32RhythmTimbreMaps[number - 64].gmRhythmKey;
+				} else {
+					debugCN(kDebugLevelSound, "[Key  %03i] -> ", number);
+					_percussionMap[i + 23] = MIDI_UNMAPPED;
+				}
+			}
+
+			if (_percussionMap[i + 23] == MIDI_UNMAPPED)
+				debugC(kDebugLevelSound, "[Unmapped]");
+			else
+				debugC(kDebugLevelSound, "%s", GmPercussionNames[_percussionMap[i + 23]]);
+
+			_percussionVelocityScale[i + 23] = *(data + pos + 4 * i + 3) * 127 / 100;
+		}
+	}
+}
+
 void MidiPlayer_Midi::setMt32Volume(byte volume) {
 	sendMt32SysEx(0x100016, &volume, 1);
 }
@@ -567,6 +742,8 @@
 		_keyShift[i] = 0;
 		_volAdjust[i] = 0;
 		_velocityMapIdx[i] = 0;
+		_pitchBendRange[i] = MIDI_UNMAPPED;
+		_percussionVelocityScale[i] = 127;
 	}
 
 	Resource *res = NULL;
@@ -592,6 +769,7 @@
 		res = resMan->findResource(ResourceId(kResourceTypePatch, 4), 0);
 
 		if (res && isMt32GmPatch(res->data, res->size)) {
+			// There is a GM patch
 			readMt32GmPatch(res->data, res->size);
 
 			// Detect the format of patch 1, so that we know what play mask to use
@@ -601,7 +779,37 @@
 			else
 				_isOldPatchFormat = !isMt32GmPatch(res->data, res->size);
 		} else {
-			warning("MT-32 to GM translation not yet supported");
+			// No GM patch found, map instruments using MT-32 patch
+
+			warning("Game has no native support for General MIDI, applying auto-mapping");
+
+			// Modify velocity map to make low velocity notes a little louder
+			for (uint i = 1; i < 0x40; i++)
+				_velocityMap[0][i] = 0x20 + (i - 1) / 2;
+
+			res = resMan->findResource(ResourceId(kResourceTypePatch, 1), 0);
+
+			if (res) {
+				if (!isMt32GmPatch(res->data, res->size))
+					mapMt32ToGm(res->data, res->size);
+				else
+					error("MT-32 patch has wrong type");
+			} else {
+				// No MT-32 patch present, try to read from MT32.DRV
+				Common::File f;
+
+				if (f.open("MT32.DRV")) {
+					int size = f.size();
+
+					assert(size >= 70);
+
+					f.seek(0x29);
+
+					// Read AdLib->MT-32 patch map
+					for (int i = 0; i < 48; i++)
+						_patchMap[i] = getGmInstrument(Mt32PresetTimbreMaps[f.readByte() & 0x7f]);
+				}
+			}
 		}
 	}
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list