FMOplMidiDriver.cpp

Go to the documentation of this file.
00001 /* 
00002  * Copyright (C) 2001  Ludvig Strigeus
00003  * Copyright (C) 2001/2002 The ScummVM project
00004  * Copyright (C) 2002 The Exult Team
00005  * Copyright (C) 2003 The Pentagram Team
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020  */
00021 
00022 #include "pent_include.h"
00023 #include "FMOplMidiDriver.h"
00024 
00025 #ifdef USE_FMOPL_MIDI
00026 
00027 #include "XMidiEvent.h"
00028 
00029 #ifdef PENTAGRAM_IN_EXULT
00030 #include "databuf.h"
00031 #else
00032 #include "IDataSource.h"
00033 #include "GameData.h"
00034 #include "MusicFlex.h"
00035 #endif
00036 
00037 #include <cmath>
00038 
00039 const MidiDriver::MidiDriverDesc FMOplMidiDriver::desc = 
00040                 MidiDriver::MidiDriverDesc ("FMOpl", createInstance);
00041 
00042 //#define LUCAS_MODE
00043 
00044 // We fudge with the velocity. If it's 16, it complies to AIL 2.0 Specs
00045 #define VEL_FUDGE 2
00046 
00047 /* This is the internal emulated MIDI driver using the included OPL2 sound chip 
00048  * FM instrument definitions below borrowed from the Allegro library by
00049  * Phil Hassey, <philhassey@hotmail.com> (www.imitationpickles.org)
00050  */
00051 
00052 const unsigned char FMOplMidiDriver::midi_fm_instruments_table[128][11] = {
00053         /* This set of GM instrument patches was provided by Jorrit Rouwe...
00054          */
00055         {0x21, 0x21, 0x8f, 0x0c, 0xf2, 0xf2, 0x45, 0x76, 0x00, 0x00, 0x08},     /* Acoustic Grand */
00056         {0x31, 0x21, 0x4b, 0x09, 0xf2, 0xf2, 0x54, 0x56, 0x00, 0x00, 0x08},     /* Bright Acoustic */
00057         {0x31, 0x21, 0x49, 0x09, 0xf2, 0xf2, 0x55, 0x76, 0x00, 0x00, 0x08},     /* Electric Grand */
00058         {0xb1, 0x61, 0x0e, 0x09, 0xf2, 0xf3, 0x3b, 0x0b, 0x00, 0x00, 0x06},     /* Honky-Tonk */
00059         {0x01, 0x21, 0x57, 0x09, 0xf1, 0xf1, 0x38, 0x28, 0x00, 0x00, 0x00},     /* Electric Piano 1 */
00060         {0x01, 0x21, 0x93, 0x09, 0xf1, 0xf1, 0x38, 0x28, 0x00, 0x00, 0x00},     /* Electric Piano 2 */
00061         {0x21, 0x36, 0x80, 0x17, 0xa2, 0xf1, 0x01, 0xd5, 0x00, 0x00, 0x08},     /* Harpsichord */
00062         {0x01, 0x01, 0x92, 0x09, 0xc2, 0xc2, 0xa8, 0x58, 0x00, 0x00, 0x0a},     /* Clav */
00063         {0x0c, 0x81, 0x5c, 0x09, 0xf6, 0xf3, 0x54, 0xb5, 0x00, 0x00, 0x00},     /* Celesta */
00064         {0x07, 0x11, 0x97, 0x89, 0xf6, 0xf5, 0x32, 0x11, 0x00, 0x00, 0x02},     /* Glockenspiel */
00065         {0x17, 0x01, 0x21, 0x09, 0x56, 0xf6, 0x04, 0x04, 0x00, 0x00, 0x02},     /* Music Box */
00066         {0x18, 0x81, 0x62, 0x09, 0xf3, 0xf2, 0xe6, 0xf6, 0x00, 0x00, 0x00},     /* Vibraphone */
00067         {0x18, 0x21, 0x23, 0x09, 0xf7, 0xe5, 0x55, 0xd8, 0x00, 0x00, 0x00},     /* Marimba */
00068         {0x15, 0x01, 0x91, 0x09, 0xf6, 0xf6, 0xa6, 0xe6, 0x00, 0x00, 0x04},     /* Xylophone */
00069         {0x45, 0x81, 0x59, 0x89, 0xd3, 0xa3, 0x82, 0xe3, 0x00, 0x00, 0x0c},     /* Tubular Bells */
00070         {0x03, 0x81, 0x49, 0x89, 0x74, 0xb3, 0x55, 0x05, 0x01, 0x00, 0x04},     /* Dulcimer */
00071         {0x71, 0x31, 0x92, 0x09, 0xf6, 0xf1, 0x14, 0x07, 0x00, 0x00, 0x02},     /* Drawbar Organ */
00072         {0x72, 0x30, 0x14, 0x09, 0xc7, 0xc7, 0x58, 0x08, 0x00, 0x00, 0x02},     /* Percussive Organ */
00073         {0x70, 0xb1, 0x44, 0x09, 0xaa, 0x8a, 0x18, 0x08, 0x00, 0x00, 0x04},     /* Rock Organ */
00074         {0x23, 0xb1, 0x93, 0x09, 0x97, 0x55, 0x23, 0x14, 0x01, 0x00, 0x04},     /* Church Organ */
00075         {0x61, 0xb1, 0x13, 0x89, 0x97, 0x55, 0x04, 0x04, 0x01, 0x00, 0x00},     /* Reed Organ */
00076         {0x24, 0xb1, 0x48, 0x09, 0x98, 0x46, 0x2a, 0x1a, 0x01, 0x00, 0x0c},     /* Accoridan */
00077         {0x61, 0x21, 0x13, 0x09, 0x91, 0x61, 0x06, 0x07, 0x01, 0x00, 0x0a},     /* Harmonica */
00078         {0x21, 0xa1, 0x13, 0x92, 0x71, 0x61, 0x06, 0x07, 0x00, 0x00, 0x06},     /* Tango Accordian */
00079         {0x02, 0x41, 0x9c, 0x89, 0xf3, 0xf3, 0x94, 0xc8, 0x01, 0x00, 0x0c},     /* Acoustic Guitar(nylon) */
00080         {0x03, 0x11, 0x54, 0x09, 0xf3, 0xf1, 0x9a, 0xe7, 0x01, 0x00, 0x0c},     /* Acoustic Guitar(steel) */
00081         {0x23, 0x21, 0x5f, 0x09, 0xf1, 0xf2, 0x3a, 0xf8, 0x00, 0x00, 0x00},     /* Electric Guitar(jazz) */
00082         {0x03, 0x21, 0x87, 0x89, 0xf6, 0xf3, 0x22, 0xf8, 0x01, 0x00, 0x06},     /* Electric Guitar(clean) */
00083         {0x03, 0x21, 0x47, 0x09, 0xf9, 0xf6, 0x54, 0x3a, 0x00, 0x00, 0x00},     /* Electric Guitar(muted) */
00084         {0x23, 0x21, 0x4a, 0x0e, 0x91, 0x84, 0x41, 0x19, 0x01, 0x00, 0x08},     /* Overdriven Guitar */
00085         {0x23, 0x21, 0x4a, 0x09, 0x95, 0x94, 0x19, 0x19, 0x01, 0x00, 0x08},     /* Distortion Guitar */
00086         {0x09, 0x84, 0xa1, 0x89, 0x20, 0xd1, 0x4f, 0xf8, 0x00, 0x00, 0x08},     /* Guitar Harmonics */
00087         {0x21, 0xa2, 0x1e, 0x09, 0x94, 0xc3, 0x06, 0xa6, 0x00, 0x00, 0x02},     /* Acoustic Bass */
00088         {0x31, 0x31, 0x12, 0x09, 0xf1, 0xf1, 0x28, 0x18, 0x00, 0x00, 0x0a},     /* Electric Bass(finger) */
00089         {0x31, 0x31, 0x8d, 0x09, 0xf1, 0xf1, 0xe8, 0x78, 0x00, 0x00, 0x0a},     /* Electric Bass(pick) */
00090         {0x31, 0x32, 0x5b, 0x09, 0x51, 0x71, 0x28, 0x48, 0x00, 0x00, 0x0c},     /* Fretless Bass */
00091         {0x01, 0x21, 0x8b, 0x49, 0xa1, 0xf2, 0x9a, 0xdf, 0x00, 0x00, 0x08},     /* Slap Bass 1 */
00092         {0x21, 0x21, 0x8b, 0x11, 0xa2, 0xa1, 0x16, 0xdf, 0x00, 0x00, 0x08},     /* Slap Bass 2 */
00093         {0x31, 0x31, 0x8b, 0x09, 0xf4, 0xf1, 0xe8, 0x78, 0x00, 0x00, 0x0a},     /* Synth Bass 1 */
00094         {0x31, 0x31, 0x12, 0x09, 0xf1, 0xf1, 0x28, 0x18, 0x00, 0x00, 0x0a},     /* Synth Bass 2 */
00095         {0x31, 0x21, 0x15, 0x09, 0xdd, 0x56, 0x13, 0x26, 0x01, 0x00, 0x08},     /* Violin */
00096         {0x31, 0x21, 0x16, 0x09, 0xdd, 0x66, 0x13, 0x06, 0x01, 0x00, 0x08},     /* Viola */
00097         {0x71, 0x31, 0x49, 0x09, 0xd1, 0x61, 0x1c, 0x0c, 0x01, 0x00, 0x08},     /* Cello */
00098         {0x21, 0x23, 0x4d, 0x89, 0x71, 0x72, 0x12, 0x06, 0x01, 0x00, 0x02},     /* Contrabass */
00099         {0xf1, 0xe1, 0x40, 0x09, 0xf1, 0x6f, 0x21, 0x16, 0x01, 0x00, 0x02},     /* Tremolo Strings */
00100         {0x02, 0x01, 0x1a, 0x89, 0xf5, 0x85, 0x75, 0x35, 0x01, 0x00, 0x00},     /* Pizzicato Strings */
00101         {0x02, 0x01, 0x1d, 0x89, 0xf5, 0xf3, 0x75, 0xf4, 0x01, 0x00, 0x00},     /* Orchestral Strings */
00102         {0x10, 0x11, 0x41, 0x09, 0xf5, 0xf2, 0x05, 0xc3, 0x01, 0x00, 0x02},     /* Timpani */
00103         {0x21, 0xa2, 0x9b, 0x0a, 0xb1, 0x72, 0x25, 0x08, 0x01, 0x00, 0x0e},     /* String Ensemble 1 */
00104         {0xa1, 0x21, 0x98, 0x09, 0x7f, 0x3f, 0x03, 0x07, 0x01, 0x01, 0x00},     /* String Ensemble 2 */
00105         {0xa1, 0x61, 0x93, 0x09, 0xc1, 0x4f, 0x12, 0x05, 0x00, 0x00, 0x0a},     /* SynthStrings 1 */
00106         {0x21, 0x61, 0x18, 0x09, 0xc1, 0x4f, 0x22, 0x05, 0x00, 0x00, 0x0c},     /* SynthStrings 2 */
00107         {0x31, 0x72, 0x5b, 0x8c, 0xf4, 0x8a, 0x15, 0x05, 0x00, 0x00, 0x00},     /* Choir Aahs */
00108         {0xa1, 0x61, 0x90, 0x09, 0x74, 0x71, 0x39, 0x67, 0x00, 0x00, 0x00},     /* Voice Oohs */
00109         {0x71, 0x72, 0x57, 0x09, 0x54, 0x7a, 0x05, 0x05, 0x00, 0x00, 0x0c},     /* Synth Voice */
00110         {0x90, 0x41, 0x00, 0x09, 0x54, 0xa5, 0x63, 0x45, 0x00, 0x00, 0x08},     /* Orchestra Hit */
00111         {0x21, 0x21, 0x92, 0x0a, 0x85, 0x8f, 0x17, 0x09, 0x00, 0x00, 0x0c},     /* Trumpet */
00112         {0x21, 0x21, 0x94, 0x0e, 0x75, 0x8f, 0x17, 0x09, 0x00, 0x00, 0x0c},     /* Trombone */
00113         {0x21, 0x61, 0x94, 0x09, 0x76, 0x82, 0x15, 0x37, 0x00, 0x00, 0x0c},     /* Tuba */
00114         {0x31, 0x21, 0x43, 0x09, 0x9e, 0x62, 0x17, 0x2c, 0x01, 0x01, 0x02},     /* Muted Trumpet */
00115         {0x21, 0x21, 0x9b, 0x09, 0x61, 0x7f, 0x6a, 0x0a, 0x00, 0x00, 0x02},     /* French Horn */
00116         {0x61, 0x22, 0x8a, 0x0f, 0x75, 0x74, 0x1f, 0x0f, 0x00, 0x00, 0x08},     /* Brass Section */
00117         {0xa1, 0x21, 0x86, 0x8c, 0x72, 0x71, 0x55, 0x18, 0x01, 0x00, 0x00},     /* SynthBrass 1 */
00118         {0x21, 0x21, 0x4d, 0x09, 0x54, 0xa6, 0x3c, 0x1c, 0x00, 0x00, 0x08},     /* SynthBrass 2 */
00119         {0x31, 0x61, 0x8f, 0x09, 0x93, 0x72, 0x02, 0x0b, 0x01, 0x00, 0x08},     /* Soprano Sax */
00120         {0x31, 0x61, 0x8e, 0x09, 0x93, 0x72, 0x03, 0x09, 0x01, 0x00, 0x08},     /* Alto Sax */
00121         {0x31, 0x61, 0x91, 0x09, 0x93, 0x82, 0x03, 0x09, 0x01, 0x00, 0x0a},     /* Tenor Sax */
00122         {0x31, 0x61, 0x8e, 0x09, 0x93, 0x72, 0x0f, 0x0f, 0x01, 0x00, 0x0a},     /* Baritone Sax */
00123         {0x21, 0x21, 0x4b, 0x09, 0xaa, 0x8f, 0x16, 0x0a, 0x01, 0x00, 0x08},     /* Oboe */
00124         {0x31, 0x21, 0x90, 0x09, 0x7e, 0x8b, 0x17, 0x0c, 0x01, 0x01, 0x06},     /* English Horn */
00125         {0x31, 0x32, 0x81, 0x09, 0x75, 0x61, 0x19, 0x19, 0x01, 0x00, 0x00},     /* Bassoon */
00126         {0x32, 0x21, 0x90, 0x09, 0x9b, 0x72, 0x21, 0x17, 0x00, 0x00, 0x04},     /* Clarinet */
00127         {0xe1, 0xe1, 0x1f, 0x09, 0x85, 0x65, 0x5f, 0x1a, 0x00, 0x00, 0x00},     /* Piccolo */
00128         {0xe1, 0xe1, 0x46, 0x09, 0x88, 0x65, 0x5f, 0x1a, 0x00, 0x00, 0x00},     /* Flute */
00129         {0xa1, 0x21, 0x9c, 0x09, 0x75, 0x75, 0x1f, 0x0a, 0x00, 0x00, 0x02},     /* Recorder */
00130         {0x31, 0x21, 0x8b, 0x09, 0x84, 0x65, 0x58, 0x1a, 0x00, 0x00, 0x00},     /* Pan Flute */
00131         {0xe1, 0xa1, 0x4c, 0x09, 0x66, 0x65, 0x56, 0x26, 0x00, 0x00, 0x00},     /* Blown Bottle */
00132         {0x62, 0xa1, 0xcb, 0x09, 0x76, 0x55, 0x46, 0x36, 0x00, 0x00, 0x00},     /* Skakuhachi */
00133         {0x62, 0xa1, 0xa2, 0x09, 0x57, 0x56, 0x07, 0x07, 0x00, 0x00, 0x0b},     /* Whistle */
00134         {0x62, 0xa1, 0x9c, 0x09, 0x77, 0x76, 0x07, 0x07, 0x00, 0x00, 0x0b},     /* Ocarina */
00135         {0x22, 0x21, 0x59, 0x09, 0xff, 0xff, 0x03, 0x0f, 0x02, 0x00, 0x00},     /* Lead 1 (square) */
00136         {0x21, 0x21, 0x0e, 0x09, 0xff, 0xff, 0x0f, 0x0f, 0x01, 0x01, 0x00},     /* Lead 2 (sawtooth) */
00137         {0x22, 0x21, 0x46, 0x89, 0x86, 0x64, 0x55, 0x18, 0x00, 0x00, 0x00},     /* Lead 3 (calliope) */
00138         {0x21, 0xa1, 0x45, 0x09, 0x66, 0x96, 0x12, 0x0a, 0x00, 0x00, 0x00},     /* Lead 4 (chiff) */
00139         {0x21, 0x22, 0x8b, 0x09, 0x92, 0x91, 0x2a, 0x2a, 0x01, 0x00, 0x00},     /* Lead 5 (charang) */
00140         {0xa2, 0x61, 0x9e, 0x49, 0xdf, 0x6f, 0x05, 0x07, 0x00, 0x00, 0x02},     /* Lead 6 (voice) */
00141         {0x20, 0x60, 0x1a, 0x09, 0xef, 0x8f, 0x01, 0x06, 0x00, 0x02, 0x00},     /* Lead 7 (fifths) */
00142         {0x21, 0x21, 0x8f, 0x86, 0xf1, 0xf4, 0x29, 0x09, 0x00, 0x00, 0x0a},     /* Lead 8 (bass+lead) */
00143         {0x77, 0xa1, 0xa5, 0x09, 0x53, 0xa0, 0x94, 0x05, 0x00, 0x00, 0x02},     /* Pad 1 (new age) */
00144         {0x61, 0xb1, 0x1f, 0x89, 0xa8, 0x25, 0x11, 0x03, 0x00, 0x00, 0x0a},     /* Pad 2 (warm) */
00145         {0x61, 0x61, 0x17, 0x09, 0x91, 0x55, 0x34, 0x16, 0x00, 0x00, 0x0c},     /* Pad 3 (polysynth) */
00146         {0x71, 0x72, 0x5d, 0x09, 0x54, 0x6a, 0x01, 0x03, 0x00, 0x00, 0x00},     /* Pad 4 (choir) */
00147         {0x21, 0xa2, 0x97, 0x09, 0x21, 0x42, 0x43, 0x35, 0x00, 0x00, 0x08},     /* Pad 5 (bowed) */
00148         {0xa1, 0x21, 0x1c, 0x09, 0xa1, 0x31, 0x77, 0x47, 0x01, 0x01, 0x00},     /* Pad 6 (metallic) */
00149         {0x21, 0x61, 0x89, 0x0c, 0x11, 0x42, 0x33, 0x25, 0x00, 0x00, 0x0a},     /* Pad 7 (halo) */
00150         {0xa1, 0x21, 0x15, 0x09, 0x11, 0xcf, 0x47, 0x07, 0x01, 0x00, 0x00},     /* Pad 8 (sweep) */
00151         {0x3a, 0x51, 0xce, 0x09, 0xf8, 0x86, 0xf6, 0x02, 0x00, 0x00, 0x02},     /* FX 1 (rain) */
00152         {0x21, 0x21, 0x15, 0x09, 0x21, 0x41, 0x23, 0x13, 0x01, 0x00, 0x00},     /* FX 2 (soundtrack) */
00153         {0x06, 0x01, 0x5b, 0x09, 0x74, 0xa5, 0x95, 0x72, 0x00, 0x00, 0x00},     /* FX 3 (crystal) */
00154         {0x22, 0x61, 0x92, 0x8c, 0xb1, 0xf2, 0x81, 0x26, 0x00, 0x00, 0x0c},     /* FX 4 (atmosphere) */
00155         {0x41, 0x42, 0x4d, 0x09, 0xf1, 0xf2, 0x51, 0xf5, 0x01, 0x00, 0x00},     /* FX 5 (brightness) */
00156         {0x61, 0xa3, 0x94, 0x89, 0x11, 0x11, 0x51, 0x13, 0x01, 0x00, 0x06},     /* FX 6 (goblins) */
00157         {0x61, 0xa1, 0x8c, 0x89, 0x11, 0x1d, 0x31, 0x03, 0x00, 0x00, 0x06},     /* FX 7 (echoes) */
00158         {0xa4, 0x61, 0x4c, 0x09, 0xf3, 0x81, 0x73, 0x23, 0x01, 0x00, 0x04},     /* FX 8 (sci-fi) */
00159         {0x02, 0x07, 0x85, 0x0c, 0xd2, 0xf2, 0x53, 0xf6, 0x00, 0x01, 0x00},     /* Sitar */
00160         {0x11, 0x13, 0x0c, 0x89, 0xa3, 0xa2, 0x11, 0xe5, 0x01, 0x00, 0x00},     /* Banjo */
00161         {0x11, 0x11, 0x06, 0x09, 0xf6, 0xf2, 0x41, 0xe6, 0x01, 0x02, 0x04},     /* Shamisen */
00162         {0x93, 0x91, 0x91, 0x09, 0xd4, 0xeb, 0x32, 0x11, 0x00, 0x01, 0x08},     /* Koto */
00163         {0x04, 0x01, 0x4f, 0x09, 0xfa, 0xc2, 0x56, 0x05, 0x00, 0x00, 0x0c},     /* Kalimba */
00164         {0x21, 0x22, 0x49, 0x09, 0x7c, 0x6f, 0x20, 0x0c, 0x00, 0x01, 0x06},     /* Bagpipe */
00165         {0x31, 0x21, 0x85, 0x09, 0xdd, 0x56, 0x33, 0x16, 0x01, 0x00, 0x0a},     /* Fiddle */
00166         {0x20, 0x21, 0x04, 0x8a, 0xda, 0x8f, 0x05, 0x0b, 0x02, 0x00, 0x06},     /* Shanai */
00167         {0x05, 0x03, 0x6a, 0x89, 0xf1, 0xc3, 0xe5, 0xe5, 0x00, 0x00, 0x06},     /* Tinkle Bell */
00168         {0x07, 0x02, 0x15, 0x09, 0xec, 0xf8, 0x26, 0x16, 0x00, 0x00, 0x0a},     /* Agogo */
00169         {0x05, 0x01, 0x9d, 0x09, 0x67, 0xdf, 0x35, 0x05, 0x00, 0x00, 0x08},     /* Steel Drums */
00170         {0x18, 0x12, 0x96, 0x09, 0xfa, 0xf8, 0x28, 0xe5, 0x00, 0x00, 0x0a},     /* Woodblock */
00171         {0x10, 0x00, 0x86, 0x0c, 0xa8, 0xfa, 0x07, 0x03, 0x00, 0x00, 0x06},     /* Taiko Drum */
00172         {0x11, 0x10, 0x41, 0x0c, 0xf8, 0xf3, 0x47, 0x03, 0x02, 0x00, 0x04},     /* Melodic Tom */
00173         {0x01, 0x10, 0x8e, 0x09, 0xf1, 0xf3, 0x06, 0x02, 0x02, 0x00, 0x0e},     /* Synth Drum */
00174         {0x0e, 0xc0, 0x00, 0x09, 0x1f, 0x1f, 0x00, 0xff, 0x00, 0x03, 0x0e},     /* Reverse Cymbal */
00175         {0x06, 0x03, 0x80, 0x91, 0xf8, 0x56, 0x24, 0x84, 0x00, 0x02, 0x0e},     /* Guitar Fret Noise */
00176         {0x0e, 0xd0, 0x00, 0x0e, 0xf8, 0x34, 0x00, 0x04, 0x00, 0x03, 0x0e},     /* Breath Noise */
00177         {0x0e, 0xc0, 0x00, 0x09, 0xf6, 0x1f, 0x00, 0x02, 0x00, 0x03, 0x0e},     /* Seashore */
00178         {0xd5, 0xda, 0x95, 0x49, 0x37, 0x56, 0xa3, 0x37, 0x00, 0x00, 0x00},     /* Bird Tweet */
00179         {0x35, 0x14, 0x5c, 0x11, 0xb2, 0xf4, 0x61, 0x15, 0x02, 0x00, 0x0a},     /* Telephone ring */
00180         {0x0e, 0xd0, 0x00, 0x09, 0xf6, 0x4f, 0x00, 0xf5, 0x00, 0x03, 0x0e},     /* Helicopter */
00181         {0x26, 0xe4, 0x00, 0x09, 0xff, 0x12, 0x01, 0x16, 0x00, 0x01, 0x0e},     /* Applause */
00182         {0x00, 0x00, 0x00, 0x09, 0xf3, 0xf6, 0xf0, 0xc9, 0x00, 0x02, 0x0e}      /* Gunshot */
00183 
00184 };
00185 
00186 /* logarithmic relationship between midi and FM volumes */
00187 const int FMOplMidiDriver::my_midi_fm_vol_table[128] = {
00188         0, 11, 16, 19, 22, 25, 27, 29, 32, 33, 35, 37, 39, 40, 42, 43,
00189         45, 46, 48, 49, 50, 51, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
00190         64, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77,
00191         78, 79, 80, 80, 81, 82, 83, 83, 84, 85, 86, 86, 87, 88, 89, 89,
00192         90, 91, 91, 92, 93, 93, 94, 95, 96, 96, 97, 97, 98, 99, 99, 100,
00193         101, 101, 102, 103, 103, 104, 104, 105, 106, 106, 107, 107, 108,
00194         109, 109, 110, 110, 111, 112, 112, 113, 113, 114, 114, 115, 115,
00195         116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122,
00196         123, 123, 124, 124, 125, 125, 126, 126, 127
00197 };
00198 
00199 /* lucas move volume table */
00200 int FMOplMidiDriver::lucas_fm_vol_table[128];
00201 
00202 const unsigned char FMOplMidiDriver::adlib_opadd[9] = { 
00203         0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12 
00204 };
00205 
00206 //
00207 // Constructor
00208 //
00209 FMOplMidiDriver::FMOplMidiDriver() : LowLevelMidiDriver()
00210 {
00211 }
00212 
00213 //
00214 // Open the device
00215 //
00216 int FMOplMidiDriver::open()
00217 {
00218         int i, j;
00219 
00220         for (i = 0; i < 128; i++) {
00221                 for (j = 0; j < 11; j++)
00222                         myinsbank[i][j] = midi_fm_instruments_table[i][j];
00223 
00224                 myinsbank[i][INDEX_PERC] = 0x80;
00225 
00226                 // Setup square root table here
00227                 lucas_fm_vol_table[i] = (int)((double)std::sqrt((double)my_midi_fm_vol_table[i]) * 11); /* TO CHANGE !!! */
00228 
00229                 // Clear the xmidibanks
00230                 xmidibanks[i] = 0;
00231         }
00232         for (i = 0; i < 16; i++) {
00233                 ch[i].inum = 0;
00234                 ch[i].xmidi = false;
00235                 ch[i].xmidi_bank = 0;
00236                 ch[i].vol = 127;
00237                 ch[i].expression = 127;
00238                 ch[i].nshift = -13;//-13;
00239                 ch[i].on = 1;
00240                 ch[i].pitchbend = 0x2000;
00241                 ch[i].pan = 64;
00242         }
00243 
00244         /* General init */
00245         for (i = 0; i < 9; i++) {
00246                 chp[i][CHP_CHAN] = -1;
00247                 chp[i][CHP_COUNTER] = 0;
00248                 chp[i][CHP_VEL] = 0;
00249         }
00250 
00251 #ifndef PENTAGRAM_IN_EXULT
00252         IDataSource *timbres = GameData::get_instance()->getMusic()->getAdlibTimbres();
00253         if (timbres) 
00254         {
00255                 loadXMIDITimbres(timbres);
00256         }
00257         else
00258         {
00259                 perr << "FMOplMidiDriver: Error, unable to load Adlib Timbres in open()" << std::endl;
00260                 return 1;
00261         }
00262         delete timbres;
00263 #endif
00264 
00265         opl = FMOpl_Pentagram::OPLCreate(OPL_TYPE_YM3812, 3579545, sample_rate);
00266 
00267         return 0;
00268 }
00269 
00270 //
00271 // Close the device
00272 //
00273 void FMOplMidiDriver::close()
00274 {
00275         // Destroy the Opl device
00276         if (opl) FMOpl_Pentagram::OPLDestroy(opl);
00277 
00278         // Reset the relevant members
00279         opl = 0;
00280 
00281         // Clear the xmidibanks
00282         for (int i = 0; i < 128; i++) {
00283                 delete xmidibanks[i];
00284                 xmidibanks[i] = 0;
00285         }
00286 
00287 }
00288 
00289 //
00290 // Generate the samples
00291 //
00292 void FMOplMidiDriver::lowLevelProduceSamples(sint16 *samples, uint32 num_samples)
00293 {
00294         if (!opl)
00295                 memset(samples, 0, num_samples * sizeof(sint16) * stereo?2:1);
00296         else if (stereo)
00297                 FMOpl_Pentagram::YM3812UpdateOne_Stereo(opl, samples, num_samples);
00298         else
00299                 FMOpl_Pentagram::YM3812UpdateOne_Mono(opl, samples, num_samples);
00300 }
00301 
00302 int FMOplMidiDriver::midi_calc_volume(int channel, int vel)
00303 {
00304         vel += (VEL_FUDGE-1)*128;
00305 
00306         int nv = (ch[channel].vol * ch[channel].expression * vel) / (16129*VEL_FUDGE);
00307 //      int nv = (ch[channel].vol * ch[channel].expression * vel) >> 14;
00308 
00309         if (nv > 127)
00310                 nv = 127;
00311 
00312         nv = my_midi_fm_vol_table[nv];
00313 
00314         return nv;
00315 }
00316 
00317 
00318 //
00319 // Send a single packed midi command to the Opl (to be played now)
00320 //
00321 void FMOplMidiDriver::send(uint32 b)
00322 {
00323         unsigned char channel = (char)(b & 0x0F);
00324 
00325         // Discard everything on channel 9 for now
00326         if (channel == 9 && !xmidibanks[127]) return;
00327 
00328         switch (b & 0xF0) {
00329         case 0x80:                                                                      /*note off */
00330                         // Quick hack, but we should never use it. since note offs will never be sent
00331                         b &= 0xFFFF;
00332         case 0x90:{                                                                     /*note on */
00333                         unsigned char note = (unsigned char)((b >> 8) & 0x7F);
00334                         unsigned char vel = (unsigned char)((b >> 16) & 0x7F);
00335                         int i, j;
00336                         int onl, on, nv;
00337                         on = -1;
00338 
00339                         // First send a note off, if it's found
00340                         for (i = 0; i < 9; i++)
00341                                 if ((chp[i][CHP_CHAN] == channel) && (chp[i][CHP_NOTE] == note)) {
00342                                         midi_fm_endnote(i);
00343                                         chp[i][CHP_CHAN] = -1;
00344                                 }
00345 
00346                         if (vel != 0 && ch[channel].on != 0) {
00347 
00348                                 // Increment each counter
00349                                 for (i = 0; i < 9; i++) chp[i][CHP_COUNTER]++;
00350 
00351                                 // Try to find the last channel that was used, that is currently unused
00352                                 j = 0; onl = 0;
00353                                 for (i = 0; i < 9; i++)
00354                                         if ((chp[i][CHP_CHAN] == -1) && (chp[i][CHP_COUNTER] > onl)) {
00355                                                 onl = chp[i][CHP_COUNTER];
00356                                                 on = i;
00357                                                 j = 1;
00358                                         }
00359 
00360                                 // If we didn't find a free chan, use the oldest chan
00361                                 if (on == -1) {
00362                                         onl = 0;
00363                                         for (i = 0; i < 9; i++)
00364                                                 if (chp[i][CHP_COUNTER] > onl) {
00365                                                         onl = chp[i][CHP_COUNTER];
00366                                                         on = i;
00367                                                 }
00368                                 }
00369 
00370                                 // If we didn't find a free note, send a note off to the Adlib for the chan we are using
00371                                 if (j == 0) midi_fm_endnote(on);
00372 
00373                                 // Send the instrument adlib
00374                                 if ((ch[channel].inum >= 0) && (ch[channel].inum < 128)) {
00375                                         if (channel == 9 && xmidibanks[127]) 
00376                                                 midi_fm_instrument(on, xmidibanks[127]->insbank[note]);
00377                                         else
00378                                                 midi_fm_instrument(on, ch[channel].ins);
00379                                 }
00380 
00381                                 // Calculate the adlib volume
00382                                 nv = midi_calc_volume(channel, vel);
00383                                 
00384                                 // Send note on
00385                                 midi_fm_playnote(on, note + ch[channel].nshift, nv * 2, ch[channel].pitchbend);
00386 
00387                                 FMOpl_Pentagram::OPLSetPan(opl,on,ch[channel].pan);
00388 
00389                                 // Update the shadows
00390                                 chp[on][CHP_CHAN] = channel;
00391                                 chp[on][CHP_NOTE] = note;
00392                                 chp[on][CHP_COUNTER] = 0;
00393                                 chp[on][CHP_VEL] = vel;
00394                         }
00395                 }
00396                 break;
00397 
00398         case 0xa0:{                                                                     /*key after touch */
00399                         unsigned char note = (unsigned char)((b >> 8) & 0x7F);
00400                         unsigned char vel = (unsigned char)((b >> 16) & 0x7F);
00401                         int nv = midi_calc_volume(channel, vel);
00402 
00403                         for (int i = 0; i < 9; i++)
00404                                 if ((chp[CHP_CHAN][0] == channel) & (chp[i][CHP_NOTE] == note)) {
00405                                         chp[i][CHP_VEL] = vel;
00406                                         midi_fm_volume(i, nv * 2);
00407                                 }
00408                 }
00409                 break;
00410 
00411         case 0xb0:{                                                                     /* control change */
00412                         int i;
00413                         unsigned char ctrl = (unsigned char)((b >> 8) & 0x7F);
00414                         unsigned char vel = (unsigned char)((b >> 16) & 0x7F);
00415 
00416                         /* FIXME: Except for Volume, the Modulation and Sustain
00417                            code is just a random guess. */
00418                         switch (ctrl) {
00419                         case 0x00:                                                              /* Bank Change */
00420                                 break;
00421                         case 0x01:                                                              /* Modulation */
00422                                 for (i = 0; i < 9; i++)
00423                                         if (chp[i][CHP_CHAN] == channel)
00424                                                 midi_write_adlib(0x20 + adlib_opadd[i], vel);
00425                                 break;
00426                         case 0x07:                                                              /* Volume */
00427                                 ch[channel].vol = vel;
00428                                 midi_update_volume(channel);
00429                                 break;
00430                         case 0x0A:                                                              /* Pan */
00431                                 ch[channel].pan = vel;
00432                                 for (i = 0; i < 9; i++)
00433                                         if (chp[i][CHP_CHAN] == channel)
00434                                                 FMOpl_Pentagram::OPLSetPan(opl,i,ch[channel].pan);
00435                                 break;
00436                         case 0x0B:                                                              /* Expression */
00437                                 ch[channel].expression = vel;
00438                                 midi_update_volume(channel);
00439                                 break;
00440                         case 0x40:                                                              /* Sustain on/off */
00441                                 for (i = 0; i < 9; i++)
00442                                         if (chp[i][CHP_CHAN] == channel)
00443                                                 midi_write_adlib(0x80 + adlib_opadd[i], vel);
00444                                 break;
00445                         case 0x5B:                                                              /* Extended depth effect */
00446                                 //debug(1,
00447                                 //                      "MIDI sub-command 0xB0 (Control Change) case %02X (Extended Depth) not handled in MIDIEMU driver.",
00448                                 //                      ctrl);
00449                                 break;
00450                         case 0x5D:                                                              /* Chorus depth */
00451                                 //debug(1,
00452                                 //                      "MIDI sub-command 0xB0 (Control Change) case %02X (Chorus Depth) not handled in MIDIEMU driver.",
00453                                 //                      ctrl);
00454                                 break;
00455                         // 
00456                         // XMIDI
00457                         //
00458                         case XMIDI_CONTROLLER_CHAN_LOCK:
00459                                 //PERR("Uh oh. Detected a XMIDI Channel Lock (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00460                                 break;
00461                         case XMIDI_CONTROLLER_CHAN_LOCK_PROT:
00462                                 //PERR("Uh oh. Detected a XMIDI Channel Lock Protect (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00463                                 break;
00464                         case XMIDI_CONTROLLER_VOICE_PROT:
00465                                 //PERR("Uh oh. Detected a XMIDI Voice Protect (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00466                                 break;
00467                         case XMIDI_CONTROLLER_TIMBRE_PROT:
00468                                 //PERR("Uh oh. Detected a XMIDI Timbre Protect (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00469                                 break;
00470                         case XMIDI_CONTROLLER_BANK_CHANGE:
00471                                 //POUT("Detected a XMIDI Bank Change (" << (int) vel << ") on channel " << (int) channel);
00472                                 // Set the bank
00473                                 ch[channel].xmidi_bank = vel;
00474                                 break;
00475                         case XMIDI_CONTROLLER_IND_CTRL_PREFIX:
00476                                 //PERR("Uh oh. Detected a XMIDI Indirect Controller Prefix (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00477                                 break;
00478                         case XMIDI_CONTROLLER_CLEAR_BB_COUNT:
00479                                 //PERR("Uh oh. Detected a XMIDI Clear Beat/Bar Count (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00480                                 break;
00481                         case XMIDI_CONTROLLER_CALLBACK_TRIG:
00482                                 //PERR("Uh oh. Detected a XMIDI Callback Trigger (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00483                                 break;
00484                         case XMIDI_CONTROLLER_SEQ_BRANCH_INDEX:
00485                                 //PERR("Uh oh. Detected a XMIDI Sequence Branch Index (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00486                                 break;
00487                         //
00488                         // END XMIDI
00489                         //
00490                         case 0x7B:                                                              /* All notes off */
00491                                 for (i = 0; i < 9; i++) {
00492                                         if (chp[i][CHP_CHAN] == channel) {
00493                                                 midi_fm_endnote(i);
00494                                                 chp[i][CHP_CHAN] = -1;
00495                                         }
00496                                 }
00497                                 break;
00498                         default:
00499                                 //PERR("MIDI sub-command 0xB0 (Control Change) case 0x" << std::hex << (int) ctrl << std::dec << " not handled in MIDIEMU driver.");
00500                                 break;
00501                         }
00502                 }
00503                 break;
00504 
00505         case 0xc0:{                                                                     /* patch change */
00506                         unsigned char instrument = (unsigned char)((b >> 8) & 0x7F);
00507                         ch[channel].inum = instrument;
00508                         //std::POUT << "Setting instrument: " << ((unsigned int) instrument) << " for chan " << ((unsigned int) channel) << std::endl;
00509 
00510                         unsigned char *ins = 0;
00511                         int b = -1;
00512                         
00513                         // Search for xmidi ins.
00514                         if (ch[channel].xmidi) for (b = ch[channel].xmidi_bank; b>=0; b--) {
00515                                 xmidibank *bank = xmidibanks[b];
00516                                 if (!bank) continue;
00517                                 if (bank->insbank[instrument][INDEX_PERC] &= 0x80) {
00518                                         ins = bank->insbank[instrument];
00519                                         break;
00520                                 }
00521                         }
00522 
00523                         if (!ins) ins = myinsbank[instrument];
00524 
00525                         for (int j = 0; j < 12; j++)
00526                                 ch[channel].ins[j] = ins[j];
00527 
00528                         //POUT("Detected a Patch Change (" << (int) instrument << ") on channel " << (int) channel << " xmidibank: " << b);
00529 
00530                 } break;
00531 
00532         case 0xd0:                                                                              /* channel touch */
00533                 //debug(1, "MIDI command 0xD0 (Channel Touch) not handled in MIDIEMU driver.");
00534                 break;
00535 
00536         case 0xe0:{     
00537                 //break;                                                /* pitch wheel */
00538                         int pitchbend = ((b >> 8) & 0x7F) | (((b >> 16) & 0x7F) << 7);
00539                         ch[channel].pitchbend = pitchbend;
00540                         for (int i = 0; i < 9; i++) {
00541                                 if (chp[i][CHP_CHAN] == channel) {
00542                                         int nv = midi_calc_volume(channel, chp[i][CHP_VEL]);
00543                                         midi_fm_playnote(i, chp[i][CHP_NOTE] + ch[channel].nshift, nv * 2, pitchbend);
00544                                 }
00545                         }
00546                 }
00547                 break;
00548 
00549         default:
00550                 //fprintf(stderr, "Unknown : %08x\n", (int)b);
00551                 break;
00552         }
00553 }
00554 
00555 void FMOplMidiDriver::midi_write_adlib(unsigned int reg, unsigned char val)
00556 {
00557         FMOpl_Pentagram::OPLWrite(opl, 0, reg);
00558         FMOpl_Pentagram::OPLWrite(opl, 1, val);
00559         adlib_data[reg] = val;
00560 }
00561 
00562 /*
00563 
00564 typedef struct 
00565 {
00566    unsigned char mod_avekm;             // 0    (20)
00567    unsigned char mod_ksl_tl;    // 1    (40)
00568    unsigned char mod_ad;                // 2    (60)
00569    unsigned char mod_sr;                // 3    (80)
00570    unsigned char mod_ws;                // 4    (E0)
00571 
00572    unsigned char fb_c;                  // 5
00573 
00574    unsigned char car_avekm;             // 6    amp, sussnd                             (20)
00575    unsigned char car_ksl_tl;    // 7    outlev, keyscale                (43)
00576    unsigned char car_ad;                // 8    Attack Delay            AR      (63)
00577    unsigned char car_sr;                // 9    SustainLev Release      DR      (83)
00578    unsigned char car_ws;                // 10   Waveform                                (E0)
00579 }
00580 AD_instrument;
00581 
00582 case 0x20:       am,vib,ksr,eg type,mul 
00583 
00584 */
00585 
00586 void FMOplMidiDriver::midi_fm_instrument(int voice, unsigned char *inst)
00587 {
00588 #if 0
00589         /* Just gotta make sure this happens because who knows when it'll be reset otherwise.... */
00590 #endif
00591 
00592 
00593 #if 0 && defined(LUCAS_MODE)
00594         midi_write_adlib(OPL_REG_KSLTL_C + adlib_opadd[voice], 0x3f);
00595         if ((inst[INDEX_FB_C] & 1) == 0)
00596                 midi_write_adlib(OPL_REG_KSLTL_M + adlib_opadd[voice], inst[INDEX_KSLTL_M]);
00597         else
00598                 midi_write_adlib(OPL_REG_KSLTL_M + adlib_opadd[voice], 0x3f);
00599 #elif 0
00600         midi_write_adlib(OPL_REG_KSLTL_M + adlib_opadd[voice], inst[INDEX_KSLTL_M]);
00601         if ((inst[INDEX_FB_C] & 1) == 0)
00602                 midi_write_adlib(OPL_REG_KSLTL_C + adlib_opadd[voice], inst[INDEX_KSLTL_C]);
00603         else
00604                 midi_write_adlib(OPL_REG_KSLTL_C + adlib_opadd[voice], 0);
00605 #else
00606 #endif
00607 
00608         midi_write_adlib(OPL_REG_AVEKM_M + adlib_opadd[voice], inst[INDEX_AVEKM_M]);
00609         midi_write_adlib(OPL_REG_KSLTL_M + adlib_opadd[voice], inst[INDEX_KSLTL_M]);
00610         midi_write_adlib(OPL_REG_AD_M + adlib_opadd[voice], inst[INDEX_AD_M]);
00611         midi_write_adlib(OPL_REG_SR_M + adlib_opadd[voice], inst[INDEX_SR_M]);
00612         midi_write_adlib(OPL_REG_WAVE_M + adlib_opadd[voice], inst[INDEX_WAVE_M]);
00613 
00614         if (!(inst[INDEX_PERC] & 0x7f)) {
00615                 midi_write_adlib(OPL_REG_AVEKM_C + adlib_opadd[voice], inst[INDEX_AVEKM_C]);
00616                 midi_write_adlib(OPL_REG_KSLTL_C + adlib_opadd[voice], inst[INDEX_KSLTL_C]);
00617                 midi_write_adlib(OPL_REG_AD_C + adlib_opadd[voice], inst[INDEX_AD_C]);
00618                 midi_write_adlib(OPL_REG_SR_C + adlib_opadd[voice], inst[INDEX_SR_C]);
00619                 midi_write_adlib(OPL_REG_WAVE_C + adlib_opadd[voice], inst[INDEX_WAVE_C]);
00620                 midi_write_adlib(OPL_REG_FB_C + voice, inst[INDEX_FB_C]);
00621                 midi_write_adlib(0xbd, 0);
00622 
00623                 if (!inst[INDEX_PERC]) {
00624                         PERR("Tried setting an instruement that wasnt loaded");
00625                 }
00626         }
00627 }
00628 
00629 void FMOplMidiDriver::midi_update_volume(int channel)
00630 {
00631         for (int i = 0; i < 9; i++)
00632                 if ((chp[i][CHP_CHAN] == channel)) {
00633 
00634                         int nv = midi_calc_volume(channel, chp[i][CHP_VEL]);
00635                         midi_fm_volume(i, nv * 2);
00636                 }
00637 }
00638 
00639 void FMOplMidiDriver::midi_fm_volume(int voice, int volume)
00640 {
00641         volume >>= 2;
00642 
00643         if ((adlib_data[0xc0 + voice] & 1) == 1)
00644                 midi_write_adlib(0x40 + adlib_opadd[voice],
00645                                                                                  (unsigned char)((63 - volume) |
00646                                                                                                                                                  (adlib_data[0x40 + adlib_opadd[voice]] & 0xc0)));
00647         midi_write_adlib(0x43 + adlib_opadd[voice],
00648                                                                          (unsigned char)((63 - volume) | (adlib_data[0x43 + adlib_opadd[voice]] & 0xc0)));
00649 }
00650 
00651 const int FMOplMidiDriver::fnums[12] =
00652         {       0x16b, 0x181, 0x198, 0x1b0, 
00653                 0x1ca, 0x1e5, 0x202, 0x220, 
00654                 0x241, 0x263, 0x287, 0x2ae };
00655 
00656 /* These tables 'borrowed' from Timidity tables.c
00657 
00658    Copyright (C) 1999-2001 Masanao Izumo <mo@goice.co.jp>
00659    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
00660 */
00661 const double FMOplMidiDriver::bend_fine[256] = {
00662         1.0, 1.0002256593050698, 1.0004513695322617, 1.0006771306930664,
00663         1.0009029427989777, 1.0011288058614922, 1.0013547198921082, 1.0015806849023274,
00664         1.0018067009036538, 1.002032767907594, 1.0022588859256572, 1.0024850549693551,
00665         1.0027112750502025, 1.0029375461797159, 1.0031638683694153, 1.0033902416308227,
00666         1.0036166659754628, 1.0038431414148634, 1.0040696679605541, 1.0042962456240678,
00667         1.0045228744169397, 1.0047495543507072, 1.0049762854369111, 1.0052030676870944,
00668         1.0054299011128027, 1.0056567857255843, 1.00588372153699, 1.006110708558573,
00669         1.0063377468018897, 1.0065648362784985, 1.0067919769999607, 1.0070191689778405,
00670         1.0072464122237039, 1.0074737067491204, 1.0077010525656616, 1.0079284496849015,
00671         1.0081558981184175, 1.008383397877789, 1.008610948974598, 1.0088385514204294,
00672         1.0090662052268706, 1.0092939104055114, 1.0095216669679448, 1.0097494749257656,
00673         1.009977334290572, 1.0102052450739643, 1.0104332072875455, 1.0106612209429215,
00674         1.0108892860517005, 1.0111174026254934, 1.0113455706759138, 1.0115737902145781,
00675         1.0118020612531047, 1.0120303838031153, 1.0122587578762337, 1.012487183484087,
00676         1.0127156606383041, 1.0129441893505169, 1.0131727696323602, 1.0134014014954713,
00677         1.0136300849514894, 1.0138588200120575, 1.0140876066888203, 1.0143164449934257,
00678         1.0145453349375237, 1.0147742765327674, 1.0150032697908125, 1.0152323147233171,
00679         1.015461411341942, 1.0156905596583505, 1.0159197596842091, 1.0161490114311862,
00680         1.0163783149109531, 1.0166076701351838, 1.0168370771155553, 1.0170665358637463,
00681         1.0172960463914391, 1.0175256087103179, 1.0177552228320703, 1.0179848887683858,
00682         1.0182146065309567, 1.0184443761314785, 1.0186741975816487, 1.0189040708931674,
00683         1.0191339960777379, 1.0193639731470658, 1.0195940021128593, 1.0198240829868295,
00684         1.0200542157806898, 1.0202844005061564, 1.0205146371749483, 1.0207449257987866,
00685         1.0209752663893958, 1.0212056589585028, 1.0214361035178368, 1.0216666000791297,
00686         1.0218971486541166, 1.0221277492545349, 1.0223584018921241, 1.0225891065786274,
00687         1.0228198633257899, 1.0230506721453596, 1.023281533049087, 1.0235124460487257,
00688         1.0237434111560313, 1.0239744283827625, 1.0242054977406807, 1.0244366192415495,
00689         1.0246677928971357, 1.0248990187192082, 1.025130296719539, 1.0253616269099028,
00690         1.0255930093020766, 1.0258244439078401, 1.0260559307389761, 1.0262874698072693,
00691         1.0265190611245079, 1.0267507047024822, 1.0269824005529853, 1.027214148687813,
00692         1.0274459491187637, 1.0276778018576387, 1.0279097069162415, 1.0281416643063788,
00693         1.0283736740398595, 1.0286057361284953, 1.0288378505841009, 1.0290700174184932,
00694         1.0293022366434921, 1.0295345082709197, 1.0297668323126017, 1.0299992087803651,
00695         1.030231637686041, 1.0304641190414621, 1.0306966528584645, 1.0309292391488862,
00696         1.0311618779245688, 1.0313945691973556, 1.0316273129790936, 1.0318601092816313,
00697         1.0320929581168212, 1.0323258594965172, 1.0325588134325767, 1.0327918199368598,
00698         1.0330248790212284, 1.0332579906975481, 1.0334911549776868, 1.033724371873515,
00699         1.0339576413969056, 1.0341909635597348, 1.0344243383738811, 1.0346577658512259,
00700         1.034891246003653, 1.0351247788430489, 1.0353583643813031, 1.0355920026303078,
00701         1.0358256936019572, 1.0360594373081489, 1.0362932337607829, 1.0365270829717617,
00702         1.0367609849529913, 1.0369949397163791, 1.0372289472738365, 1.0374630076372766,
00703         1.0376971208186156, 1.0379312868297725, 1.0381655056826686, 1.0383997773892284,
00704         1.0386341019613787, 1.0388684794110492, 1.0391029097501721, 1.0393373929906822,
00705         1.0395719291445176, 1.0398065182236185, 1.0400411602399278, 1.0402758552053915,
00706         1.0405106031319582, 1.0407454040315787, 1.0409802579162071, 1.0412151647977996,
00707         1.0414501246883161, 1.0416851375997183, 1.0419202035439705, 1.0421553225330404,
00708         1.042390494578898, 1.042625719693516, 1.0428609978888699, 1.043096329176938,
00709         1.0433317135697009, 1.0435671510791424, 1.0438026417172486, 1.0440381854960086,
00710         1.0442737824274138, 1.044509432523459, 1.044745135796141, 1.0449808922574599,
00711         1.0452167019194181, 1.0454525647940205, 1.0456884808932754, 1.0459244502291931,
00712         1.0461604728137874, 1.0463965486590741, 1.046632677777072, 1.0468688601798024,
00713         1.0471050958792898, 1.047341384887561, 1.0475777272166455, 1.047814122878576,
00714         1.048050571885387, 1.0482870742491166, 1.0485236299818055, 1.0487602390954964,
00715         1.0489969016022356, 1.0492336175140715, 1.0494703868430555, 1.0497072096012419,
00716         1.0499440858006872, 1.0501810154534512, 1.050417998571596, 1.0506550351671864,
00717         1.0508921252522903, 1.0511292688389782, 1.0513664659393229, 1.0516037165654004,
00718         1.0518410207292894, 1.0520783784430709, 1.0523157897188296, 1.0525532545686513,
00719         1.0527907730046264, 1.0530283450388465, 1.0532659706834067, 1.0535036499504049,
00720         1.0537413828519411, 1.0539791694001188, 1.0542170096070436, 1.0544549034848243,
00721         1.0546928510455722, 1.0549308523014012, 1.0551689072644284, 1.0554070159467728,
00722         1.0556451783605572, 1.0558833945179062, 1.0561216644309479, 1.0563599881118126,
00723         1.0565983655726334, 1.0568367968255465, 1.0570752818826903, 1.0573138207562065,
00724         1.057552413458239, 1.0577910600009348, 1.0580297603964437, 1.058268514656918,
00725         1.0585073227945128, 1.0587461848213857, 1.058985100749698, 1.0592240705916123
00726 };
00727 
00728 const double FMOplMidiDriver::bend_coarse[128] = {
00729         1.0, 1.0594630943592953, 1.122462048309373, 1.189207115002721,
00730         1.2599210498948732, 1.3348398541700344, 1.4142135623730951, 1.4983070768766815,
00731         1.5874010519681994, 1.681792830507429, 1.7817974362806785, 1.8877486253633868,
00732         2.0, 2.1189261887185906, 2.244924096618746, 2.3784142300054421,
00733         2.5198420997897464, 2.6696797083400687, 2.8284271247461903, 2.996614153753363,
00734         3.1748021039363992, 3.363585661014858, 3.5635948725613571, 3.7754972507267741,
00735         4.0, 4.2378523774371812, 4.4898481932374912, 4.7568284600108841,
00736         5.0396841995794928, 5.3393594166801366, 5.6568542494923806, 5.993228307506727,
00737         6.3496042078727974, 6.727171322029716, 7.1271897451227151, 7.5509945014535473,
00738         8.0, 8.4757047548743625, 8.9796963864749824, 9.5136569200217682,
00739         10.079368399158986, 10.678718833360273, 11.313708498984761, 11.986456615013454,
00740         12.699208415745595, 13.454342644059432, 14.25437949024543, 15.101989002907095,
00741         16.0, 16.951409509748721, 17.959392772949972, 19.027313840043536,
00742         20.158736798317967, 21.357437666720553, 22.627416997969522, 23.972913230026901,
00743         25.398416831491197, 26.908685288118864, 28.508758980490853, 30.203978005814196,
00744         32.0, 33.902819019497443, 35.918785545899944, 38.054627680087073,
00745         40.317473596635935, 42.714875333441107, 45.254833995939045, 47.945826460053802,
00746         50.796833662982394, 53.817370576237728, 57.017517960981706, 60.407956011628393,
00747         64.0, 67.805638038994886, 71.837571091799887, 76.109255360174146,
00748         80.63494719327187, 85.429750666882214, 90.509667991878089, 95.891652920107603,
00749         101.59366732596479, 107.63474115247546, 114.03503592196341, 120.81591202325679,
00750         128.0, 135.61127607798977, 143.67514218359977, 152.21851072034829,
00751         161.26989438654374, 170.85950133376443, 181.01933598375618, 191.78330584021521,
00752         203.18733465192958, 215.26948230495091, 228.07007184392683, 241.63182404651357,
00753         256.0, 271.22255215597971, 287.35028436719938, 304.43702144069658,
00754         322.53978877308765, 341.71900266752868, 362.03867196751236, 383.56661168043064,
00755         406.37466930385892, 430.53896460990183, 456.14014368785394, 483.26364809302686,
00756         512.0, 542.44510431195943, 574.70056873439876, 608.87404288139317,
00757         645.0795775461753, 683.43800533505737, 724.07734393502471, 767.13322336086128,
00758         812.74933860771785, 861.07792921980365, 912.28028737570787, 966.52729618605372,
00759         1024.0, 1084.8902086239189, 1149.4011374687975, 1217.7480857627863,
00760         1290.1591550923506, 1366.8760106701147, 1448.1546878700494, 1534.2664467217226
00761 };
00762 
00763 void FMOplMidiDriver::midi_fm_playnote(int voice, int note, int volume, int pitchbend)
00764 {
00765         int freq = fnums[note % 12];
00766         int oct = note / 12;
00767         int c;
00768         float pf;
00769 
00770         pitchbend -= 0x2000;
00771         if (pitchbend != 0) {
00772                 pitchbend *= 2;
00773                 if (pitchbend >= 0)
00774                         pf = (float)(bend_fine[(pitchbend >> 5) & 0xFF] * bend_coarse[(pitchbend >> 13) & 0x7F]);
00775                 else {
00776                         pitchbend = -pitchbend;
00777                         pf =
00778                                 (float)(1.0 / (bend_fine[(pitchbend >> 5) & 0xFF] * bend_coarse[(pitchbend >> 13) & 0x7F]));
00779                 }
00780                 freq = (int)((float)freq * pf);
00781 
00782                 while (freq >= (fnums[0] * 2)) {
00783                         freq /= 2;
00784                         oct += 1;
00785                 }
00786                 while (freq < fnums[0]) {
00787                         freq *= 2;
00788                         oct -= 1;
00789                 }
00790         }
00791 
00792         midi_fm_volume(voice, volume);
00793         midi_write_adlib(0xa0 + voice, (unsigned char)(freq & 0xff));
00794 
00795         c = ((freq & 0x300) >> 8) + (oct << 2) + (1 << 5);
00796         midi_write_adlib(0xb0 + voice, (unsigned char)c);
00797 }
00798 
00799 void FMOplMidiDriver::midi_fm_endnote(int voice)
00800 {
00801         midi_write_adlib(0xb0 + voice, (unsigned char)(adlib_data[0xb0 + voice] & (255 - 32)));
00802 }
00803 
00804 void FMOplMidiDriver::loadTimbreLibrary(IDataSource *ds, TimbreLibraryType type)
00805 {
00806         int i;
00807 
00808         // Clear the xmidibanks
00809         for (i = 0; i < 128; i++) {
00810                 delete xmidibanks[i];
00811                 xmidibanks[i] = 0;
00812         }
00813 
00814         for (i = 0; i < 16; i++) ch[i].xmidi = false;
00815 
00816         if (type == TIMBRE_LIBRARY_XMIDI_AD) 
00817                 loadXMIDITimbres(ds);
00818         else if (type == TIMBRE_LIBRARY_U7VOICE_AD) 
00819                 loadU7VoiceTimbres(ds);
00820 }
00821 
00822 void FMOplMidiDriver::loadXMIDITimbres(IDataSource *ds)
00823 {
00824         bool read[128];
00825         std::memset(read, false, sizeof(read));
00826 
00827         // Read all the timbres
00828         uint32 i;
00829         for (i = 0; ds->getPos() < ds->getSize(); i++) {
00830                 // Seek to the entry
00831                 ds->seek(i*6);
00832 
00833                 uint32 patch = (uint8) ds->read1();
00834                 uint32 bank = (uint8) ds->read1();
00835 
00836                 // If we read both == 255 then we've read all of them
00837                 if (patch == 255 || bank == 255) {
00838                         //POUT ("Finished " << patch << ": ");
00839                         break;
00840                 }
00841 
00842                 // Get offset and seek to it
00843                 uint32 offset = ds->read4();
00844 
00845                 //POUT ("Patch " << i << " = " << bank << ":" << patch << " @ " << offset);
00846 
00847                 // Check to see if the bank exists
00848                 if (!xmidibanks[bank]) {
00849                         xmidibanks[bank] = new xmidibank;
00850                         std::memset (xmidibanks[bank], 0, sizeof (xmidibank));
00851                 }
00852 
00853                 // Seek to offset
00854                 ds->seek(offset);
00855 
00856                 // Get len of the entry
00857                 uint16 len = ds->read2();
00858 
00859                 // Only accept lens that are 0xC
00860                 if (len != 0xE) {
00861                         POUT ("Invalid Patch " << bank << ":" << patch << " len was " << len << " " << std::hex << len << std::dec);
00862                         //continue;
00863                 }
00864 
00865                 // Skip 1 byte
00866                 ds->skip(1);
00867 
00868                 struct
00869                 {
00870                    unsigned char mod_avekm;             // 0    (20)
00871                    unsigned char mod_ksl_tl;    // 1    (40)
00872                    unsigned char mod_ad;                // 2    (60)
00873                    unsigned char mod_sr;                // 3    (80)
00874                    unsigned char mod_ws;                // 4    (E0)
00875 
00876                    unsigned char fb_c;                  // 5
00877 
00878                    unsigned char car_avekm;             // 6    amp, sussnd                             (20)
00879                    unsigned char car_ksl_tl;    // 7    outlev, keyscale                (43)
00880                    unsigned char car_ad;                // 8    Attack Delay            AR      (63)
00881                    unsigned char car_sr;                // 9    SustainLev Release      DR      (83)
00882                    unsigned char car_ws;                // 10   Waveform                                (E0)
00883                 } xmidi_ins;
00884 
00885                 ds->read(&xmidi_ins, 11);
00886 
00887                 unsigned char* ins = xmidibanks[bank]->insbank[patch];
00888 
00889                 ins[INDEX_AVEKM_M] = xmidi_ins.mod_avekm;
00890                 ins[INDEX_KSLTL_M] = xmidi_ins.mod_ksl_tl;
00891                 ins[INDEX_AD_M] = xmidi_ins.mod_ad;
00892                 ins[INDEX_SR_M] = xmidi_ins.mod_sr;
00893                 ins[INDEX_WAVE_M] = xmidi_ins.mod_ws;
00894                 ins[INDEX_AVEKM_C] = xmidi_ins.car_avekm;
00895                 ins[INDEX_KSLTL_C] = xmidi_ins.car_ksl_tl;
00896                 ins[INDEX_AD_C] = xmidi_ins.car_ad;
00897                 ins[INDEX_SR_C] = xmidi_ins.car_sr;
00898                 ins[INDEX_WAVE_C] = xmidi_ins.car_ws;
00899                 ins[INDEX_FB_C] = xmidi_ins.fb_c;
00900                 ins[INDEX_PERC] = 0x80; // Note that XMIDI uses a different method to U7:TBG
00901         }
00902 
00903 //      POUT ("FMOplMidiDriver: " << i << " timbres read");
00904 
00905         for (i = 0; i < 16; i++) ch[i].xmidi = true;
00906 }
00907 
00908 void FMOplMidiDriver::loadU7VoiceTimbres(IDataSource *ds)
00909 {
00910         struct u7voice_adlib_ins {
00911                 unsigned char mod_avekm;                        // 0:   (20)
00912                 unsigned char mod_ksl_tl;                       // 1:   (40)
00913                 unsigned char mod_ad;                           // 2:   (60)
00914                 unsigned char mod_sr;                           // 3:   (80)
00915                 unsigned char mod_ws;                           // 4:   (E0)
00916                 
00917                 unsigned char car_avekm;                        // 5:   amp, sussnd                             (22)
00918                 unsigned char car_ksl_tl;                       // 6:   outlev, keyscale                (43)
00919                 unsigned char car_ad;                           // 7:   Attack Delay            AR      (63)
00920                 unsigned char car_sr;                           // 8:   SustainLev Release      DR      (83)
00921                 unsigned char car_ws;                           // 9:   Waveform                                (E3)
00922                 
00923                 unsigned char fb_c;                                     // 10:  Feedback/Connection
00924                 
00925                 // NOT IMPLEMENTED from here on!
00926                 
00927                 unsigned char perc_voice;                       // 11   Percussion voice number !! 
00928                                                                                         // (0=melodic, 6=bass drum, etc.)
00929                 
00930                 unsigned char car_vel_sense;            // 12:  carrier velocity sensitivity                                    
00931                 unsigned char mod_vel_sense;            // 13:  modulator velocity sensitivity                                  
00932                 unsigned char bend_sense;                       // 14:  pitch bend sensitivity                                                  
00933                 unsigned char wheel_sense;                      // 15:  modulation wheel sensitivity                
00934                 unsigned char lfo_speed;                        // 16:  lfo speed                                   
00935                 unsigned char lfo_depth;                        // 17:  lfo depth                                   
00936                 
00937                 unsigned short pe_start_level;          // 18-19:  pitch envelope start level
00938                 unsigned short pe_attack_rate1;         // 20-21:  pitch envelope attack rate 1
00939                 unsigned short pe_attack_level1;        // 22-23:  pitch envelope attack level 1
00940                 unsigned short pe_attack_rate2;         // 24-25:  pitch envelope attack rate 2
00941                 unsigned short pe_attack_level2;        // 26-27:  pitch envelope attack level 2
00942                 unsigned short pe_decay_rate;           // 28-29:  pitch envelope decay rate
00943                 unsigned short pe_sustain_level;        // 30-31:  pitch envelope sustain level
00944                 unsigned short pe_release_rate;         // 32-33:  pitch envelope release rate
00945                 unsigned short pe_end_level;            // 34-35:  pitch envelope end level
00946                 
00947                 unsigned char deturn;                           // 36:  detune
00948                 unsigned char transpose;                        // 37:  transpose
00949                 unsigned char next_partial;                     // 38:  next partial number (+1; 0=no more partials)
00950                 unsigned char key_follow;                       // 39:  key follow
00951                 unsigned char reserved[7];                      // 40-46:  reserved
00952                 
00953                 unsigned char prog_num;                         // 47:  program change number
00954                 
00955                 void read(IDataSource *ds) {
00956                         mod_avekm = ds->read1();
00957                         mod_ksl_tl = ds->read1();
00958                         mod_ad = ds->read1();
00959                         mod_sr = ds->read1();
00960                         mod_ws = ds->read1();
00961                         car_avekm = ds->read1();
00962                         car_ksl_tl = ds->read1();
00963                         car_ad = ds->read1();
00964                         car_sr = ds->read1();
00965                         car_ws = ds->read1();
00966                         fb_c = ds->read1();
00967                 
00968                         // NOT IMPLEMENTED from here on!
00969                 
00970                         perc_voice = ds->read1();
00971                 
00972                         car_vel_sense = ds->read1();
00973                         mod_vel_sense = ds->read1();
00974                         bend_sense = ds->read1();
00975                         wheel_sense = ds->read1();
00976                         lfo_speed = ds->read1();
00977                         lfo_depth = ds->read1();
00978                 
00979                         pe_start_level = ds->read2();
00980                         pe_attack_rate1 = ds->read2();
00981                         pe_attack_level1 = ds->read2();
00982                         pe_attack_rate2 = ds->read2();
00983                         pe_attack_level2 = ds->read2();
00984                         pe_decay_rate = ds->read2();
00985                         pe_sustain_level = ds->read2();
00986                         pe_release_rate = ds->read2();
00987                         pe_end_level = ds->read2();
00988                 
00989                         deturn = ds->read1();
00990                         transpose = ds->read1();
00991                         next_partial = ds->read1();
00992                         key_follow = ds->read1();
00993                         ds->read((char *) reserved, 7);
00994                 
00995                         prog_num = ds->read1();
00996                 }
00997         } u7voice_ins;
00998 
00999         //POUT("Size of u7voice_adlib_ins " << sizeof(u7voice_adlib_ins));
01000 
01001         int count = ds->read1() & 0xFF;
01002 
01003         // Read all the timbres
01004         int i;
01005         for (i = 0; i < count; i++) {
01006 
01007                 // Read the timbre
01008                 u7voice_ins.read(ds);
01009 
01010                 uint32 patch = u7voice_ins.prog_num;
01011                 uint32 bank = 0;
01012 
01013                 //POUT ("Patch " << i << " = " << bank << ":" << patch);
01014 
01015                 // Check to see if the bank exists
01016                 if (!xmidibanks[bank]) {
01017                         xmidibanks[bank] = new xmidibank;
01018                         std::memset (xmidibanks[bank], 0, sizeof (xmidibank));
01019                 }
01020 
01021                 if (patch > 127) {
01022                         //PERR ("Don't know how to handle this");
01023                         continue;
01024                 }
01025 
01026                 unsigned char* ins = xmidibanks[bank]->insbank[patch];
01027 
01028                 ins[INDEX_AVEKM_M] = u7voice_ins.mod_avekm;
01029                 ins[INDEX_KSLTL_M] = u7voice_ins.mod_ksl_tl;
01030                 ins[INDEX_AD_M] = u7voice_ins.mod_ad;
01031                 ins[INDEX_SR_M] = u7voice_ins.mod_sr;
01032                 ins[INDEX_WAVE_M] = u7voice_ins.mod_ws;
01033                 ins[INDEX_AVEKM_C] = u7voice_ins.car_avekm;
01034                 ins[INDEX_KSLTL_C] = u7voice_ins.car_ksl_tl;
01035                 ins[INDEX_AD_C] = u7voice_ins.car_ad;
01036                 ins[INDEX_SR_C] = u7voice_ins.car_sr;
01037                 ins[INDEX_WAVE_C] = u7voice_ins.car_ws;
01038                 ins[INDEX_FB_C] = u7voice_ins.fb_c;
01039                 ins[INDEX_PERC] = u7voice_ins.perc_voice | 0x80;        // Note that XMIDI uses a different method to U7:TBG
01040 
01041                 if (u7voice_ins.next_partial || u7voice_ins.key_follow) {
01042                 //      POUT("next_partial " << (int) u7voice_ins.next_partial << "  key_follow " << (int) u7voice_ins.key_follow);
01043                 }
01044         }
01045 
01046         //POUT (i << " timbres read");
01047 
01048         for (i = 0; i < 16; i++) ch[i].xmidi = true;
01049 }
01050 
01051 
01052 #endif // USE_FMOPL_MIDI

Generated on Fri Jul 27 22:27:15 2007 for pentagram by  doxygen 1.4.7