00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00043
00044
00045 #define VEL_FUDGE 2
00046
00047
00048
00049
00050
00051
00052 const unsigned char FMOplMidiDriver::midi_fm_instruments_table[128][11] = {
00053
00054
00055 {0x21, 0x21, 0x8f, 0x0c, 0xf2, 0xf2, 0x45, 0x76, 0x00, 0x00, 0x08},
00056 {0x31, 0x21, 0x4b, 0x09, 0xf2, 0xf2, 0x54, 0x56, 0x00, 0x00, 0x08},
00057 {0x31, 0x21, 0x49, 0x09, 0xf2, 0xf2, 0x55, 0x76, 0x00, 0x00, 0x08},
00058 {0xb1, 0x61, 0x0e, 0x09, 0xf2, 0xf3, 0x3b, 0x0b, 0x00, 0x00, 0x06},
00059 {0x01, 0x21, 0x57, 0x09, 0xf1, 0xf1, 0x38, 0x28, 0x00, 0x00, 0x00},
00060 {0x01, 0x21, 0x93, 0x09, 0xf1, 0xf1, 0x38, 0x28, 0x00, 0x00, 0x00},
00061 {0x21, 0x36, 0x80, 0x17, 0xa2, 0xf1, 0x01, 0xd5, 0x00, 0x00, 0x08},
00062 {0x01, 0x01, 0x92, 0x09, 0xc2, 0xc2, 0xa8, 0x58, 0x00, 0x00, 0x0a},
00063 {0x0c, 0x81, 0x5c, 0x09, 0xf6, 0xf3, 0x54, 0xb5, 0x00, 0x00, 0x00},
00064 {0x07, 0x11, 0x97, 0x89, 0xf6, 0xf5, 0x32, 0x11, 0x00, 0x00, 0x02},
00065 {0x17, 0x01, 0x21, 0x09, 0x56, 0xf6, 0x04, 0x04, 0x00, 0x00, 0x02},
00066 {0x18, 0x81, 0x62, 0x09, 0xf3, 0xf2, 0xe6, 0xf6, 0x00, 0x00, 0x00},
00067 {0x18, 0x21, 0x23, 0x09, 0xf7, 0xe5, 0x55, 0xd8, 0x00, 0x00, 0x00},
00068 {0x15, 0x01, 0x91, 0x09, 0xf6, 0xf6, 0xa6, 0xe6, 0x00, 0x00, 0x04},
00069 {0x45, 0x81, 0x59, 0x89, 0xd3, 0xa3, 0x82, 0xe3, 0x00, 0x00, 0x0c},
00070 {0x03, 0x81, 0x49, 0x89, 0x74, 0xb3, 0x55, 0x05, 0x01, 0x00, 0x04},
00071 {0x71, 0x31, 0x92, 0x09, 0xf6, 0xf1, 0x14, 0x07, 0x00, 0x00, 0x02},
00072 {0x72, 0x30, 0x14, 0x09, 0xc7, 0xc7, 0x58, 0x08, 0x00, 0x00, 0x02},
00073 {0x70, 0xb1, 0x44, 0x09, 0xaa, 0x8a, 0x18, 0x08, 0x00, 0x00, 0x04},
00074 {0x23, 0xb1, 0x93, 0x09, 0x97, 0x55, 0x23, 0x14, 0x01, 0x00, 0x04},
00075 {0x61, 0xb1, 0x13, 0x89, 0x97, 0x55, 0x04, 0x04, 0x01, 0x00, 0x00},
00076 {0x24, 0xb1, 0x48, 0x09, 0x98, 0x46, 0x2a, 0x1a, 0x01, 0x00, 0x0c},
00077 {0x61, 0x21, 0x13, 0x09, 0x91, 0x61, 0x06, 0x07, 0x01, 0x00, 0x0a},
00078 {0x21, 0xa1, 0x13, 0x92, 0x71, 0x61, 0x06, 0x07, 0x00, 0x00, 0x06},
00079 {0x02, 0x41, 0x9c, 0x89, 0xf3, 0xf3, 0x94, 0xc8, 0x01, 0x00, 0x0c},
00080 {0x03, 0x11, 0x54, 0x09, 0xf3, 0xf1, 0x9a, 0xe7, 0x01, 0x00, 0x0c},
00081 {0x23, 0x21, 0x5f, 0x09, 0xf1, 0xf2, 0x3a, 0xf8, 0x00, 0x00, 0x00},
00082 {0x03, 0x21, 0x87, 0x89, 0xf6, 0xf3, 0x22, 0xf8, 0x01, 0x00, 0x06},
00083 {0x03, 0x21, 0x47, 0x09, 0xf9, 0xf6, 0x54, 0x3a, 0x00, 0x00, 0x00},
00084 {0x23, 0x21, 0x4a, 0x0e, 0x91, 0x84, 0x41, 0x19, 0x01, 0x00, 0x08},
00085 {0x23, 0x21, 0x4a, 0x09, 0x95, 0x94, 0x19, 0x19, 0x01, 0x00, 0x08},
00086 {0x09, 0x84, 0xa1, 0x89, 0x20, 0xd1, 0x4f, 0xf8, 0x00, 0x00, 0x08},
00087 {0x21, 0xa2, 0x1e, 0x09, 0x94, 0xc3, 0x06, 0xa6, 0x00, 0x00, 0x02},
00088 {0x31, 0x31, 0x12, 0x09, 0xf1, 0xf1, 0x28, 0x18, 0x00, 0x00, 0x0a},
00089 {0x31, 0x31, 0x8d, 0x09, 0xf1, 0xf1, 0xe8, 0x78, 0x00, 0x00, 0x0a},
00090 {0x31, 0x32, 0x5b, 0x09, 0x51, 0x71, 0x28, 0x48, 0x00, 0x00, 0x0c},
00091 {0x01, 0x21, 0x8b, 0x49, 0xa1, 0xf2, 0x9a, 0xdf, 0x00, 0x00, 0x08},
00092 {0x21, 0x21, 0x8b, 0x11, 0xa2, 0xa1, 0x16, 0xdf, 0x00, 0x00, 0x08},
00093 {0x31, 0x31, 0x8b, 0x09, 0xf4, 0xf1, 0xe8, 0x78, 0x00, 0x00, 0x0a},
00094 {0x31, 0x31, 0x12, 0x09, 0xf1, 0xf1, 0x28, 0x18, 0x00, 0x00, 0x0a},
00095 {0x31, 0x21, 0x15, 0x09, 0xdd, 0x56, 0x13, 0x26, 0x01, 0x00, 0x08},
00096 {0x31, 0x21, 0x16, 0x09, 0xdd, 0x66, 0x13, 0x06, 0x01, 0x00, 0x08},
00097 {0x71, 0x31, 0x49, 0x09, 0xd1, 0x61, 0x1c, 0x0c, 0x01, 0x00, 0x08},
00098 {0x21, 0x23, 0x4d, 0x89, 0x71, 0x72, 0x12, 0x06, 0x01, 0x00, 0x02},
00099 {0xf1, 0xe1, 0x40, 0x09, 0xf1, 0x6f, 0x21, 0x16, 0x01, 0x00, 0x02},
00100 {0x02, 0x01, 0x1a, 0x89, 0xf5, 0x85, 0x75, 0x35, 0x01, 0x00, 0x00},
00101 {0x02, 0x01, 0x1d, 0x89, 0xf5, 0xf3, 0x75, 0xf4, 0x01, 0x00, 0x00},
00102 {0x10, 0x11, 0x41, 0x09, 0xf5, 0xf2, 0x05, 0xc3, 0x01, 0x00, 0x02},
00103 {0x21, 0xa2, 0x9b, 0x0a, 0xb1, 0x72, 0x25, 0x08, 0x01, 0x00, 0x0e},
00104 {0xa1, 0x21, 0x98, 0x09, 0x7f, 0x3f, 0x03, 0x07, 0x01, 0x01, 0x00},
00105 {0xa1, 0x61, 0x93, 0x09, 0xc1, 0x4f, 0x12, 0x05, 0x00, 0x00, 0x0a},
00106 {0x21, 0x61, 0x18, 0x09, 0xc1, 0x4f, 0x22, 0x05, 0x00, 0x00, 0x0c},
00107 {0x31, 0x72, 0x5b, 0x8c, 0xf4, 0x8a, 0x15, 0x05, 0x00, 0x00, 0x00},
00108 {0xa1, 0x61, 0x90, 0x09, 0x74, 0x71, 0x39, 0x67, 0x00, 0x00, 0x00},
00109 {0x71, 0x72, 0x57, 0x09, 0x54, 0x7a, 0x05, 0x05, 0x00, 0x00, 0x0c},
00110 {0x90, 0x41, 0x00, 0x09, 0x54, 0xa5, 0x63, 0x45, 0x00, 0x00, 0x08},
00111 {0x21, 0x21, 0x92, 0x0a, 0x85, 0x8f, 0x17, 0x09, 0x00, 0x00, 0x0c},
00112 {0x21, 0x21, 0x94, 0x0e, 0x75, 0x8f, 0x17, 0x09, 0x00, 0x00, 0x0c},
00113 {0x21, 0x61, 0x94, 0x09, 0x76, 0x82, 0x15, 0x37, 0x00, 0x00, 0x0c},
00114 {0x31, 0x21, 0x43, 0x09, 0x9e, 0x62, 0x17, 0x2c, 0x01, 0x01, 0x02},
00115 {0x21, 0x21, 0x9b, 0x09, 0x61, 0x7f, 0x6a, 0x0a, 0x00, 0x00, 0x02},
00116 {0x61, 0x22, 0x8a, 0x0f, 0x75, 0x74, 0x1f, 0x0f, 0x00, 0x00, 0x08},
00117 {0xa1, 0x21, 0x86, 0x8c, 0x72, 0x71, 0x55, 0x18, 0x01, 0x00, 0x00},
00118 {0x21, 0x21, 0x4d, 0x09, 0x54, 0xa6, 0x3c, 0x1c, 0x00, 0x00, 0x08},
00119 {0x31, 0x61, 0x8f, 0x09, 0x93, 0x72, 0x02, 0x0b, 0x01, 0x00, 0x08},
00120 {0x31, 0x61, 0x8e, 0x09, 0x93, 0x72, 0x03, 0x09, 0x01, 0x00, 0x08},
00121 {0x31, 0x61, 0x91, 0x09, 0x93, 0x82, 0x03, 0x09, 0x01, 0x00, 0x0a},
00122 {0x31, 0x61, 0x8e, 0x09, 0x93, 0x72, 0x0f, 0x0f, 0x01, 0x00, 0x0a},
00123 {0x21, 0x21, 0x4b, 0x09, 0xaa, 0x8f, 0x16, 0x0a, 0x01, 0x00, 0x08},
00124 {0x31, 0x21, 0x90, 0x09, 0x7e, 0x8b, 0x17, 0x0c, 0x01, 0x01, 0x06},
00125 {0x31, 0x32, 0x81, 0x09, 0x75, 0x61, 0x19, 0x19, 0x01, 0x00, 0x00},
00126 {0x32, 0x21, 0x90, 0x09, 0x9b, 0x72, 0x21, 0x17, 0x00, 0x00, 0x04},
00127 {0xe1, 0xe1, 0x1f, 0x09, 0x85, 0x65, 0x5f, 0x1a, 0x00, 0x00, 0x00},
00128 {0xe1, 0xe1, 0x46, 0x09, 0x88, 0x65, 0x5f, 0x1a, 0x00, 0x00, 0x00},
00129 {0xa1, 0x21, 0x9c, 0x09, 0x75, 0x75, 0x1f, 0x0a, 0x00, 0x00, 0x02},
00130 {0x31, 0x21, 0x8b, 0x09, 0x84, 0x65, 0x58, 0x1a, 0x00, 0x00, 0x00},
00131 {0xe1, 0xa1, 0x4c, 0x09, 0x66, 0x65, 0x56, 0x26, 0x00, 0x00, 0x00},
00132 {0x62, 0xa1, 0xcb, 0x09, 0x76, 0x55, 0x46, 0x36, 0x00, 0x00, 0x00},
00133 {0x62, 0xa1, 0xa2, 0x09, 0x57, 0x56, 0x07, 0x07, 0x00, 0x00, 0x0b},
00134 {0x62, 0xa1, 0x9c, 0x09, 0x77, 0x76, 0x07, 0x07, 0x00, 0x00, 0x0b},
00135 {0x22, 0x21, 0x59, 0x09, 0xff, 0xff, 0x03, 0x0f, 0x02, 0x00, 0x00},
00136 {0x21, 0x21, 0x0e, 0x09, 0xff, 0xff, 0x0f, 0x0f, 0x01, 0x01, 0x00},
00137 {0x22, 0x21, 0x46, 0x89, 0x86, 0x64, 0x55, 0x18, 0x00, 0x00, 0x00},
00138 {0x21, 0xa1, 0x45, 0x09, 0x66, 0x96, 0x12, 0x0a, 0x00, 0x00, 0x00},
00139 {0x21, 0x22, 0x8b, 0x09, 0x92, 0x91, 0x2a, 0x2a, 0x01, 0x00, 0x00},
00140 {0xa2, 0x61, 0x9e, 0x49, 0xdf, 0x6f, 0x05, 0x07, 0x00, 0x00, 0x02},
00141 {0x20, 0x60, 0x1a, 0x09, 0xef, 0x8f, 0x01, 0x06, 0x00, 0x02, 0x00},
00142 {0x21, 0x21, 0x8f, 0x86, 0xf1, 0xf4, 0x29, 0x09, 0x00, 0x00, 0x0a},
00143 {0x77, 0xa1, 0xa5, 0x09, 0x53, 0xa0, 0x94, 0x05, 0x00, 0x00, 0x02},
00144 {0x61, 0xb1, 0x1f, 0x89, 0xa8, 0x25, 0x11, 0x03, 0x00, 0x00, 0x0a},
00145 {0x61, 0x61, 0x17, 0x09, 0x91, 0x55, 0x34, 0x16, 0x00, 0x00, 0x0c},
00146 {0x71, 0x72, 0x5d, 0x09, 0x54, 0x6a, 0x01, 0x03, 0x00, 0x00, 0x00},
00147 {0x21, 0xa2, 0x97, 0x09, 0x21, 0x42, 0x43, 0x35, 0x00, 0x00, 0x08},
00148 {0xa1, 0x21, 0x1c, 0x09, 0xa1, 0x31, 0x77, 0x47, 0x01, 0x01, 0x00},
00149 {0x21, 0x61, 0x89, 0x0c, 0x11, 0x42, 0x33, 0x25, 0x00, 0x00, 0x0a},
00150 {0xa1, 0x21, 0x15, 0x09, 0x11, 0xcf, 0x47, 0x07, 0x01, 0x00, 0x00},
00151 {0x3a, 0x51, 0xce, 0x09, 0xf8, 0x86, 0xf6, 0x02, 0x00, 0x00, 0x02},
00152 {0x21, 0x21, 0x15, 0x09, 0x21, 0x41, 0x23, 0x13, 0x01, 0x00, 0x00},
00153 {0x06, 0x01, 0x5b, 0x09, 0x74, 0xa5, 0x95, 0x72, 0x00, 0x00, 0x00},
00154 {0x22, 0x61, 0x92, 0x8c, 0xb1, 0xf2, 0x81, 0x26, 0x00, 0x00, 0x0c},
00155 {0x41, 0x42, 0x4d, 0x09, 0xf1, 0xf2, 0x51, 0xf5, 0x01, 0x00, 0x00},
00156 {0x61, 0xa3, 0x94, 0x89, 0x11, 0x11, 0x51, 0x13, 0x01, 0x00, 0x06},
00157 {0x61, 0xa1, 0x8c, 0x89, 0x11, 0x1d, 0x31, 0x03, 0x00, 0x00, 0x06},
00158 {0xa4, 0x61, 0x4c, 0x09, 0xf3, 0x81, 0x73, 0x23, 0x01, 0x00, 0x04},
00159 {0x02, 0x07, 0x85, 0x0c, 0xd2, 0xf2, 0x53, 0xf6, 0x00, 0x01, 0x00},
00160 {0x11, 0x13, 0x0c, 0x89, 0xa3, 0xa2, 0x11, 0xe5, 0x01, 0x00, 0x00},
00161 {0x11, 0x11, 0x06, 0x09, 0xf6, 0xf2, 0x41, 0xe6, 0x01, 0x02, 0x04},
00162 {0x93, 0x91, 0x91, 0x09, 0xd4, 0xeb, 0x32, 0x11, 0x00, 0x01, 0x08},
00163 {0x04, 0x01, 0x4f, 0x09, 0xfa, 0xc2, 0x56, 0x05, 0x00, 0x00, 0x0c},
00164 {0x21, 0x22, 0x49, 0x09, 0x7c, 0x6f, 0x20, 0x0c, 0x00, 0x01, 0x06},
00165 {0x31, 0x21, 0x85, 0x09, 0xdd, 0x56, 0x33, 0x16, 0x01, 0x00, 0x0a},
00166 {0x20, 0x21, 0x04, 0x8a, 0xda, 0x8f, 0x05, 0x0b, 0x02, 0x00, 0x06},
00167 {0x05, 0x03, 0x6a, 0x89, 0xf1, 0xc3, 0xe5, 0xe5, 0x00, 0x00, 0x06},
00168 {0x07, 0x02, 0x15, 0x09, 0xec, 0xf8, 0x26, 0x16, 0x00, 0x00, 0x0a},
00169 {0x05, 0x01, 0x9d, 0x09, 0x67, 0xdf, 0x35, 0x05, 0x00, 0x00, 0x08},
00170 {0x18, 0x12, 0x96, 0x09, 0xfa, 0xf8, 0x28, 0xe5, 0x00, 0x00, 0x0a},
00171 {0x10, 0x00, 0x86, 0x0c, 0xa8, 0xfa, 0x07, 0x03, 0x00, 0x00, 0x06},
00172 {0x11, 0x10, 0x41, 0x0c, 0xf8, 0xf3, 0x47, 0x03, 0x02, 0x00, 0x04},
00173 {0x01, 0x10, 0x8e, 0x09, 0xf1, 0xf3, 0x06, 0x02, 0x02, 0x00, 0x0e},
00174 {0x0e, 0xc0, 0x00, 0x09, 0x1f, 0x1f, 0x00, 0xff, 0x00, 0x03, 0x0e},
00175 {0x06, 0x03, 0x80, 0x91, 0xf8, 0x56, 0x24, 0x84, 0x00, 0x02, 0x0e},
00176 {0x0e, 0xd0, 0x00, 0x0e, 0xf8, 0x34, 0x00, 0x04, 0x00, 0x03, 0x0e},
00177 {0x0e, 0xc0, 0x00, 0x09, 0xf6, 0x1f, 0x00, 0x02, 0x00, 0x03, 0x0e},
00178 {0xd5, 0xda, 0x95, 0x49, 0x37, 0x56, 0xa3, 0x37, 0x00, 0x00, 0x00},
00179 {0x35, 0x14, 0x5c, 0x11, 0xb2, 0xf4, 0x61, 0x15, 0x02, 0x00, 0x0a},
00180 {0x0e, 0xd0, 0x00, 0x09, 0xf6, 0x4f, 0x00, 0xf5, 0x00, 0x03, 0x0e},
00181 {0x26, 0xe4, 0x00, 0x09, 0xff, 0x12, 0x01, 0x16, 0x00, 0x01, 0x0e},
00182 {0x00, 0x00, 0x00, 0x09, 0xf3, 0xf6, 0xf0, 0xc9, 0x00, 0x02, 0x0e}
00183
00184 };
00185
00186
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
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
00208
00209 FMOplMidiDriver::FMOplMidiDriver() : LowLevelMidiDriver()
00210 {
00211 }
00212
00213
00214
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
00227 lucas_fm_vol_table[i] = (int)((double)std::sqrt((double)my_midi_fm_vol_table[i]) * 11);
00228
00229
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;
00239 ch[i].on = 1;
00240 ch[i].pitchbend = 0x2000;
00241 ch[i].pan = 64;
00242 }
00243
00244
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
00272
00273 void FMOplMidiDriver::close()
00274 {
00275
00276 if (opl) FMOpl_Pentagram::OPLDestroy(opl);
00277
00278
00279 opl = 0;
00280
00281
00282 for (int i = 0; i < 128; i++) {
00283 delete xmidibanks[i];
00284 xmidibanks[i] = 0;
00285 }
00286
00287 }
00288
00289
00290
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
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
00320
00321 void FMOplMidiDriver::send(uint32 b)
00322 {
00323 unsigned char channel = (char)(b & 0x0F);
00324
00325
00326 if (channel == 9 && !xmidibanks[127]) return;
00327
00328 switch (b & 0xF0) {
00329 case 0x80:
00330
00331 b &= 0xFFFF;
00332 case 0x90:{
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
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
00349 for (i = 0; i < 9; i++) chp[i][CHP_COUNTER]++;
00350
00351
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
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
00371 if (j == 0) midi_fm_endnote(on);
00372
00373
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
00382 nv = midi_calc_volume(channel, vel);
00383
00384
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
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:{
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:{
00412 int i;
00413 unsigned char ctrl = (unsigned char)((b >> 8) & 0x7F);
00414 unsigned char vel = (unsigned char)((b >> 16) & 0x7F);
00415
00416
00417
00418 switch (ctrl) {
00419 case 0x00:
00420 break;
00421 case 0x01:
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:
00427 ch[channel].vol = vel;
00428 midi_update_volume(channel);
00429 break;
00430 case 0x0A:
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:
00437 ch[channel].expression = vel;
00438 midi_update_volume(channel);
00439 break;
00440 case 0x40:
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:
00446
00447
00448
00449 break;
00450 case 0x5D:
00451
00452
00453
00454 break;
00455
00456
00457
00458 case XMIDI_CONTROLLER_CHAN_LOCK:
00459
00460 break;
00461 case XMIDI_CONTROLLER_CHAN_LOCK_PROT:
00462
00463 break;
00464 case XMIDI_CONTROLLER_VOICE_PROT:
00465
00466 break;
00467 case XMIDI_CONTROLLER_TIMBRE_PROT:
00468
00469 break;
00470 case XMIDI_CONTROLLER_BANK_CHANGE:
00471
00472
00473 ch[channel].xmidi_bank = vel;
00474 break;
00475 case XMIDI_CONTROLLER_IND_CTRL_PREFIX:
00476
00477 break;
00478 case XMIDI_CONTROLLER_CLEAR_BB_COUNT:
00479
00480 break;
00481 case XMIDI_CONTROLLER_CALLBACK_TRIG:
00482
00483 break;
00484 case XMIDI_CONTROLLER_SEQ_BRANCH_INDEX:
00485
00486 break;
00487
00488
00489
00490 case 0x7B:
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
00500 break;
00501 }
00502 }
00503 break;
00504
00505 case 0xc0:{
00506 unsigned char instrument = (unsigned char)((b >> 8) & 0x7F);
00507 ch[channel].inum = instrument;
00508
00509
00510 unsigned char *ins = 0;
00511 int b = -1;
00512
00513
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
00529
00530 } break;
00531
00532 case 0xd0:
00533
00534 break;
00535
00536 case 0xe0:{
00537
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
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
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 void FMOplMidiDriver::midi_fm_instrument(int voice, unsigned char *inst)
00587 {
00588 #if 0
00589
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
00657
00658
00659
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
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
00828 uint32 i;
00829 for (i = 0; ds->getPos() < ds->getSize(); i++) {
00830
00831 ds->seek(i*6);
00832
00833 uint32 patch = (uint8) ds->read1();
00834 uint32 bank = (uint8) ds->read1();
00835
00836
00837 if (patch == 255 || bank == 255) {
00838
00839 break;
00840 }
00841
00842
00843 uint32 offset = ds->read4();
00844
00845
00846
00847
00848 if (!xmidibanks[bank]) {
00849 xmidibanks[bank] = new xmidibank;
00850 std::memset (xmidibanks[bank], 0, sizeof (xmidibank));
00851 }
00852
00853
00854 ds->seek(offset);
00855
00856
00857 uint16 len = ds->read2();
00858
00859
00860 if (len != 0xE) {
00861 POUT ("Invalid Patch " << bank << ":" << patch << " len was " << len << " " << std::hex << len << std::dec);
00862
00863 }
00864
00865
00866 ds->skip(1);
00867
00868 struct
00869 {
00870 unsigned char mod_avekm;
00871 unsigned char mod_ksl_tl;
00872 unsigned char mod_ad;
00873 unsigned char mod_sr;
00874 unsigned char mod_ws;
00875
00876 unsigned char fb_c;
00877
00878 unsigned char car_avekm;
00879 unsigned char car_ksl_tl;
00880 unsigned char car_ad;
00881 unsigned char car_sr;
00882 unsigned char car_ws;
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;
00901 }
00902
00903
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;
00912 unsigned char mod_ksl_tl;
00913 unsigned char mod_ad;
00914 unsigned char mod_sr;
00915 unsigned char mod_ws;
00916
00917 unsigned char car_avekm;
00918 unsigned char car_ksl_tl;
00919 unsigned char car_ad;
00920 unsigned char car_sr;
00921 unsigned char car_ws;
00922
00923 unsigned char fb_c;
00924
00925
00926
00927 unsigned char perc_voice;
00928
00929
00930 unsigned char car_vel_sense;
00931 unsigned char mod_vel_sense;
00932 unsigned char bend_sense;
00933 unsigned char wheel_sense;
00934 unsigned char lfo_speed;
00935 unsigned char lfo_depth;
00936
00937 unsigned short pe_start_level;
00938 unsigned short pe_attack_rate1;
00939 unsigned short pe_attack_level1;
00940 unsigned short pe_attack_rate2;
00941 unsigned short pe_attack_level2;
00942 unsigned short pe_decay_rate;
00943 unsigned short pe_sustain_level;
00944 unsigned short pe_release_rate;
00945 unsigned short pe_end_level;
00946
00947 unsigned char deturn;
00948 unsigned char transpose;
00949 unsigned char next_partial;
00950 unsigned char key_follow;
00951 unsigned char reserved[7];
00952
00953 unsigned char prog_num;
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
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
01000
01001 int count = ds->read1() & 0xFF;
01002
01003
01004 int i;
01005 for (i = 0; i < count; i++) {
01006
01007
01008 u7voice_ins.read(ds);
01009
01010 uint32 patch = u7voice_ins.prog_num;
01011 uint32 bank = 0;
01012
01013
01014
01015
01016 if (!xmidibanks[bank]) {
01017 xmidibanks[bank] = new xmidibank;
01018 std::memset (xmidibanks[bank], 0, sizeof (xmidibank));
01019 }
01020
01021 if (patch > 127) {
01022
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;
01040
01041 if (u7voice_ins.next_partial || u7voice_ins.key_follow) {
01042
01043 }
01044 }
01045
01046
01047
01048 for (i = 0; i < 16; i++) ch[i].xmidi = true;
01049 }
01050
01051
01052 #endif // USE_FMOPL_MIDI