fmopldrv.cc

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

Generated on Mon Jul 9 14:42:41 2007 for ExultEngine by  doxygen 1.5.1